📅  最后修改于: 2023-12-03 15:27:35.318000             🧑  作者: Mango
本题目要求给定数组中的所有无序对进行按位与操作,并将结果累加。其中数组中的无序对指任意两个不同的元素i和j,满足i<j。
要求给定数组中所有无序对的按位与,可以将数组中的所有元素转化为二进制位形式进行分析。对于每一位,我们可以通过遍历所有元素,并检验每一位的值,统计该位为1的元素的数量。
当统计某一位为1的元素数量时,我们可以采用如下思路:
对于每一个元素,找到当前位的值,并更新当前位为1的数量。
将当前位为1的数量和为0的数量相乘,便可以得到当前元素对答案的贡献。
将所有元素对答案的贡献求和,即可得到最终的按位与结果。
由于我们对每一位进行的操作都是独立的,因此可以使用位运算来优化计算过程。具体来说,我们可以使用一个int型变量来表示当前位的1的数量,每当遍历到一个元素时,将其和当前位1的数量进行与操作,并更新1的数量。
下面是本题的代码实现。具体的注释已经写在代码中。
public int rangeBitwiseAnd(int[] nums) {
int res = 0;
// 遍历二进制位的每一位
for (int i = 0; i < 32; i++) {
int cnt = 0;
// 统计当前位为1的元素的数量
for (int j = 0; j < nums.length; j++) {
cnt += (nums[j] & (1 << i)) == 0 ? 0 : 1;
}
// 计算当前位为1的元素的数量和为0的元素的数量的乘积
res += cnt * (nums.length - cnt) * (1 << i);
}
return res;
}
以上就是本题的解题思路和代码实现,该方法的时间复杂度为O(32n)=O(n),空间复杂度为O(1)。需要注意的是,本题目中的无序对是任意两个不同的元素i和j,满足i<j。而在实际的编程中,我们往往采用i<j来遍历所有元素对,这两种方式的区别在于开头统计的位置。若采用任意两个不同的元素对,那么需要从i=1开始遍历;若采用i<j的方式,那么需要从i=0开始遍历。