📅  最后修改于: 2023-12-03 15:28:04.628000             🧑  作者: Mango
给定一个数组,计算其中所有数字两两组合的按位 XOR 值和按位 AND 值,并计算有多少对数字满足按位 XOR 值大于按位 AND 值。
最朴素的想法是暴力枚举所有数字对并计算它们的按位 XOR 和按位 AND,然后统计大于小于的数量。这个做法的时间复杂度是 $O(n^2)$。
更好的做法是观察按位 XOR 和按位 AND 的定义,发现按位 XOR 和按位 AND 是对每一位进行独立的操作。因此,对于每一位,我们可以分别计算这一位的按位 XOR 和按位 AND,然后一起考虑,得到该位上满足条件的数字对数,最终求和即可。
具体来说,假设当前考虑的位是第 $i$ 位:
因此,我们只需要用 $4$ 个计数器分别统计每一种情况的数字对数目,然后根据上面的结论计算贡献即可。
时间复杂度 $O(32n)$,需要对每一位进行 $4$ 次计数,共 $32$ 位,因此每次计算的时间复杂度是 $O(4n)$。
from typing import List
def count_pairs(arr: List[int]) -> int:
n = len(arr)
ans = 0
for i in range(32):
bit_xor_1 = bit_and_0 = 0 # x_i = 0, y_i = 1
bit_xor_0 = bit_and_1 = 0 # x_i = 1, y_i = 0
for x in arr:
if x & (1 << i):
bit_and_1 += 1
if x & (1 << i) == 0:
bit_and_0 += 1
if x >> i & 1:
bit_xor_1 += 1
else:
bit_xor_0 += 1
# 等于 1 时才有贡献
ans += bit_xor_1 * bit_and_0 + bit_xor_0 * bit_and_1
return ans
时间复杂度 $O(32n)$,空间复杂度 $O(1)$。