📅  最后修改于: 2023-12-03 15:21:33.551000             🧑  作者: Mango
给定两个长度相同的数组,计算这两个数组中所有对的按位与的总和。例如,给定数组 arr1 = [1, 2, 3]
和数组 arr2 = [2, 3, 4]
,它们中所有对的按位与分别为 1&2=0
、1&3=1
、1&4=0
、2&2=2
、2&3=2
、2&4=0
、3&2=2
、3&3=3
、3&4=0
,其总和为 0+1+0+2+2+0+2+3+0=10
。
对于每一位上都有“与运算规则”,即两个数在相同位置上的数都为1时结果为1,否则结果为0。所以对于两个数组中每一个数,我们可以用二进制的方式将它们拆开,然后两两按位与。
注意到,无论两个数在某个特定位置上的数相不相同,在这个位置上的结果最多也就只有0或者1两种可能,而且这个位置的值只能是1或者0,所以我们可以用一个长度为32的数组 bitcount
来维护所有位置上1的个数,这个数组的初始化为0。
对于每一个数,我们将它与 bitcount
进行按位与,然后在 bitcount
上对应的位置上加上这个数在这个位置上的值。
最后,对于任意两个数组中的数 arr1[i]
和 arr2[j]
,它们的对应位置的按位与结果即为 arr1[i] & arr2[j]
,将结果加到答案中。
class Solution:
def countAndSum(self, arr1: List[int], arr2: List[int]) -> int:
n = len(arr1)
bitcount = [0] * 32
for i in range(n):
num = arr1[i]
for j in range(32):
bitcount[j] += num & 1
num >>= 1
ans = 0
for i in range(n):
num = arr2[i]
tmp = 0
for j in range(32):
if num & (1 << j):
tmp += bitcount[j] * (1 << j)
ans += tmp
return ans
该算法时间复杂度为 $O(32n)=O(n)$,其中 $n$ 为数组的长度。空间复杂度为 $O(32)=O(1)$,只需要一个长度为32的数组来维护每个位置上1的个数。