📌  相关文章
📜  计算给定数组中按位XOR大于K的对(1)

📅  最后修改于: 2023-12-03 15:28:04.644000             🧑  作者: Mango

计算给定数组中按位XOR大于K的对

给定一个非空整数数组和一个整数 k,找出在该数组中所有按位异或操作结果大于 k 的数对数量。

示例

输入: nums = [1, 3, 5, 7, 9], k = 5
输出: 4
解释: 有四个数对符合条件:(1, 7), (1, 9), (3, 5) 和 (3, 7)。

解题思路

我们可以使用双重循环来计算每一对数之间的异或结果,然后统计异或结果大于 k 的数量。这种方法的时间复杂度为 O(n^2)。

更优秀的方法是使用位运算的性质。我们可以从二进制位的角度来考虑这个问题。假设 x 和 y 分别是数组中的两个整数,它们的二进制表示分别为 x1x2...xm 和 y1y2...yn。这两个数的异或结果为:

x ^ y = (x1y1) (x2y2) ... (xmyn)

那么如果 x ^ y > k,那么必定有某个二进制位上 x 和 y 的对应位中的其中之一为 1,同时另一个对应位为 0。我们只需要分别统计下数组中每个数在某一二进制位上 1 的个数,然后根据异或的结果,计算出有多少个符合条件的数对即可。

代码实现
def countPairs(nums: List[int], k: int) -> int:
    # 用字典来统计每个数字在每个二进制位上出现 1 的次数
    bit_count = defaultdict(int)
    for num in nums:
        for i in range(31):
            bit_count[i] += (num >> i) & 1
    
    result = 0
    for num in nums:
        x, count = num, 0
        for i in range(31):
            if (x >> i) & 1:
                count += bit_count[i]
        # 如果 x ^ y > k,则说明 y 在某个二进制位上的对应位与 x 相反
        # 因此 y 在这个二进制位上的对应位为 0,因此此处需要将 count 减去 y 在这个二进制位上出现 1 的次数
        result += count - bit_count[k] if k != 0 else count - bit_count[0]
    
    # 由于每个对数会被重复计算两次,因此最后结果需要除以 2
    return result // 2

代码中使用了 Python 的 defaultdict 类来实现对每个数字的二进制位上出现 1 的次数的统计,可以使代码更加简洁。具体实现可以参考官方文档:https://docs.python.org/3/library/collections.html#collections.defaultdict。