leetcode
leetcode 2201 ~ 2250
所有子序列和的按位或

所有子序列和的按位或

难度:

标签:

题目描述

代码结果

运行时间: 64 ms, 内存: 25.9 MB


/*
* 使用Java Stream API求数组元素总和的题解
* 题目思路:
* 1. 使用Stream API中的sum()方法对数组进行求和。
* 2. 返回累加的结果。
*/

import java.util.Arrays;

public class ArraySumStream {
    public static int sum(int[] nums) {
        return Arrays.stream(nums).sum();
    }

    public static void main(String[] args) {
        int[] nums = {1, 2, 3, 4};
        System.out.println(sum(nums)); // 输出10
    }
}

解释

方法:

此题解的核心思路是通过操作位来计算所有子序列的按位或的和。首先,利用Python内置的reduce函数和按位或操作ior,计算出给定数组nums中所有元素的按位或结果(变量mask)。然后,通过计算nums的所有元素之和的位长度,确定可能的最大位数,以此创建一个全1的掩码(变量ans)。接下来,从最低位开始,逐位检查mask的每一位,如果该位为0,则在ans对应的位上置0,以此去除不需要的最高位。最终,ans中剩下的即为所有子序列和的按位或结果。

时间复杂度:

O(n + log C)

空间复杂度:

O(1)

代码细节讲解

🦆
题解中提到使用`reduce`和`ior`函数来计算所有元素的按位或结果,能否详细解释这两个函数是如何被应用的,以及它们的工作原理?
`reduce`函数是一个高阶函数,它接收一个二元操作函数和一个序列,然后重复应用这个函数到序列的元素上,直到序列被归约为一个单一的值。在本题中,`reduce`使用`ior`函数作为操作函数。`ior`是`operator`模块中的函数,代表按位或操作。通过`reduce(ior, nums)`,我们可以连续对数组`nums`中的所有元素执行按位或操作,从而得到一个整数,这个整数的每一个位上的值表示该位在数组中至少有一个元素是1。这样,就能有效地计算出所有元素的按位或结果,这个结果是所有可能子序列按位或的上界。
🦆
在题解中,创建了一个全1的掩码`ans`,为什么要根据`sum(nums).bit_length()`来确定掩码的位数?
在题解中使用`sum(nums).bit_length()`来确定掩码位数的原因是,这个值代表将数组中的所有元素相加后的和所需的最小位数。这是因为所有元素的总和代表了可能的最大数值范围,而其二进制位长度则反映了代表该数值所需的最大位数。通过创建一个全1的掩码,其位数等于`sum(nums)`的位长度,可以确保掩码足够大,能覆盖所有可能的按位或结果。这种方法确保了在后续的操作中不会因位数不足而丢失重要信息。
🦆
初始化时检查`max(nums) == 0`直接返回0的逻辑是基于什么考虑?在所有元素为0的情况下,按位或运算的结果有何特性?
检查`max(nums) == 0`并直接返回0的逻辑基于按位或运算的特性。按位或运算的结果中的每一位都是对应位上至少有一个1时该位才为1。如果数组中的最大值是0,意味着数组中的所有元素都是0,因此任何子序列的按位或结果也将是0。因为在所有元素都是0的情况下,无论组合多少个0,其按位或的结果仍然是0。这个检查是一个优化步骤,可以在明确结果为0的情况下避免不必要的计算。

相关问题