📌  相关文章
📜  最小化与给定数组元素进行XOR运算的K(1)

📅  最后修改于: 2023-12-03 14:55:20.468000             🧑  作者: Mango

最小化与给定数组元素进行XOR运算的K

问题背景

给定一个非空且仅包含正整数的数组nums和一个正整数k,找出一个数m使得minimize(nums[i] XOR m) for i in range(len(nums))),同时满足m XOR k <= m,其中XOR表示按位异或运算符。

解题思路
暴力枚举

一个简单的解法是对于每个数m,计算其与所有nums[i]的异或值,找到其中的最小值,最后比较m XOR k与m的大小关系,确定答案是否合法。时间复杂度为O(n^2),对于数据规模较小的情况可以接受。

Trie树

稍微优化一下暴力枚举的做法,可以通过记录nums数组中的所有数的二进制位构成的Trie树,简化每个数与nums[i]异或的计算。具体来说,对于每个数num,将其从高到低的二进制位插入到Trie树中,同时记录对应的终端节点的路径(0表示当前位为0,1表示为1),表示num对应为止的异或结果。对于每个m,则按照Trie树的规则,从高到低遍历所有对应的位,根据异或结果是否为1,在Trie树中选择相应方向的子节点进行遍历,在到达终端节点时,即可得到m与num异或的结果,从而比较得到最小值。时间复杂度为O(nlogm),其中m为数组nums中最大数的二进制位数。

位运算

利用异或的性质x XOR y = z => x XOR z = y,可知对于任意的m和num,有m XOR num XOR num = m。因此,将所有的nums[i]插入到一个Trie树中,然后从高到低遍历所有的m的二进制位,对于每一位,选择让异或结果为0的方向(即num的当前位为m的当前位的取反),如果不存在这样的方向,就只能选择异或结果为1的方向。这个过程可以通过记录Trie树中0和1方向的节点个数来实现。代码如下:

class Solution:
    def __init__(self):
        self.trie = {}
        self.max_bit = 31    # 假设最大数只有31位
        self.nodes = [[0, 0] for _ in range(self.max_bit + 1)]

    def findMaximumXOR(self, nums: List[int], k: int) -> int:
        for num in nums:
            node = self.trie
            for i in range(self.max_bit, -1, -1):
                bit = (num >> i) & 1
                if bit not in node:
                    node[bit] = {}
                node = node[bit]

        max_xor = 0
        for num in nums:
            node = self.trie
            xor = 0
            for i in range(self.max_bit, -1, -1):
                bit = (num >> i) & 1
                if self.nodes[i][bit ^ 1] > 0:
                    node = node[bit ^ 1]
                    xor += (1 << i)
                else:
                    node = node[bit]
            max_xor = max(max_xor, xor)

        if k != 0:
            node = self.trie
            xor = 0
            for i in range(self.max_bit, -1, -1):
                bit = (k >> i) & 1
                if self.nodes[i][bit] > 0:
                    node = node[bit]
                    xor += (bit << i)
                else:
                    node = node[bit ^ 1]
                    xor += ((bit ^ 1) << i)
            if xor ^ k <= xor:
                max_xor = max(max_xor, xor ^ k)

        return max_xor
参考链接