返回

难中带“hard”,取巧解LeetCode 421

后端

导读
LeetCode 421:“数组中两个数字的最大异或值”是一道颇具挑战性的算法题,它考察了二进制和Trie树等计算机科学的基本概念。这篇文章将通过Python语言,带领你一步步解决这个问题,并对代码和算法进行详细的分析。

问题
给定一个整数数组nums,你需要找到两个数字,使得它们之间的异或值最大。

解决方案
这道题的难点在于,如何有效地找到两个数字,使得它们的异或值最大。我们可以使用Trie树来解决这个问题。

Trie树是一种树状数据结构,它将一个字符串存储在一个树中,使得可以快速地查找和检索字符串。在我们的问题中,我们可以将每个整数转换为二进制字符串,然后将这些二进制字符串存储在Trie树中。这样,我们就可以快速地找到两个二进制字符串,使得它们的异或值最大。

代码实现

class TrieNode:
    def __init__(self):
        self.children = {}
        self.is_end = False

class Trie:
    def __init__(self):
        self.root = TrieNode()

    def insert(self, num):
        """
        将一个整数插入Trie树中。

        :param num: 要插入的整数。
        """
        binary_str = bin(num)[2:]
        cur = self.root
        for bit in binary_str:
            if bit not in cur.children:
                cur.children[bit] = TrieNode()
            cur = cur.children[bit]
        cur.is_end = True

    def find_max_xor(self, num):
        """
        找到与给定整数异或值最大的整数。

        :param num: 给定整数。

        :return: 与给定整数异或值最大的整数。
        """
        binary_str = bin(num)[2:]
        cur = self.root
        max_xor = 0
        for bit in binary_str:
            if (bit == '0' and '1' in cur.children) or (bit == '1' and '0' in cur.children):
                if bit == '0':
                    max_xor |= 1 << (len(binary_str) - 1 - i)
                cur = cur.children['1' if bit == '0' else '0']
            else:
                cur = cur.children[bit]
        return max_xor

def max_xor(nums):
    """
    找到数组中两个数字的最大异或值。

    :param nums: 整数数组。

    :return: 数组中两个数字的最大异或值。
    """
    trie = Trie()
    for num in nums:
        trie.insert(num)
    max_xor_value = 0
    for num in nums:
        max_xor_value = max(max_xor_value, trie.find_max_xor(num))
    return max_xor_value

if __name__ == "__main__":
    nums = [3, 10, 5, 25, 2, 8]
    print(max_xor(nums))  # 输出:28

复杂度分析

  • 时间复杂度:
    • 插入一个整数到Trie树的时间复杂度为O(log n),其中n是整数的位数。
    • 找到与给定整数异或值最大的整数的时间复杂度为O(log n)。
    • 因此,总的时间复杂度为O(n log n),其中n是数组的长度。
  • 空间复杂度:
    • Trie树的空间复杂度为O(n log n),其中n是数组的长度。

结语

LeetCode 421:“数组中两个数字的最大异或值”是一道难度位 Hard 的题,但有了合适的思路,我们能够借助二进制和 Trie 树的知识巧妙地解决问题。希望这篇文章能够对你的编程之旅有所帮助。