【算法思考记录】力扣2935. 找出强数对的最大异或值【Python3,位运算,哈希表】

力扣2935. 找出强数对的最大异或值

题目概述

题目编号:2935
题目难度:困难
相关标签:数组, 排序, 位运算

给定一个整数数组 nums,任务是找出其中可以形成的所谓“强数对”的最大异或值。强数对定义为一对整数 (x) 和 (y),满足 |x - y| ≤ \leq min(x, y)。

示例分析

  1. 示例 1
    输入:nums = [1,2,3,4,5]
    输出:7
    分析:数组中的强数对及其异或值有多种组合,其中 3 XOR 4 = 7 是最大的。

  2. 示例 2
    输入:nums = [10,100]
    输出:0
    分析:仅有 (10, 10)(100, 100) 两个强数对,它们的异或值均为 0。

  3. 示例 3
    输入:nums = [500,520,2500,3000]
    输出:1020
    分析:最大异或值来自 500 XOR 520 = 1020

解题思路

算法关键在于找到使异或值最大化的数对。首先,对数组进行排序,以便后续操作。主要思路是从最高位开始,检查是否存在两个数使得该位为 1,同时满足强数对条件。

  1. 使用掩码(mask)来逐位检查。
  2. 通过位运算和哈希表(seen)来快速判断是否存在满足条件的数对。
  3. 掩码用于保留数的前缀部分,以便对每个位的影响进行评估。

代码解析

  • 排序:首先对 nums 排序,以简化强数对的确定。
  • 位运算:使用位运算来逐步构建最大的异或值。
  • 哈希表:使用哈希表来存储和快速检索数对。
  • 掩码运算:掩码用于保留数字的高位部分,以检查每个位的贡献。

完整代码

class Solution:
    def maximumStrongPairXor(self, nums: List[int]) -> int:
        nums.sort()
        mask = 0
        ans = 0
        hb = max(nums).bit_length()
        for i in range(hb, -1, -1):
            mask |= 1 << i
            new_ans = ans | (1 << i)
            """
            如果要使得第i位为1,,要满足两个条件
            1.存在mask_x ^ mask_y = new_ans
            2.存在abs(x - y) <= min(x, y)

            对于第二个条件来说,
            可以设x <= y,此时条件2可以化简成y <= 2 * x
            因为nums已经有序,所以对于已经迭代过的元素就可以是“x”。
            那么,可以维护一个哈希表,检查是否存在一个x可以满足y <= 2 * x

            为了满足条件1,只考虑这个x的前i位,后面的位置为0,也就是mask_x,
            mask_x必须满足mask_x ^ mask_y = new_ans。
            那么,可以创建一个哈希表seen,以mask_x为键,以x为值。
            """
            seen = {}
            for y in nums:
                mask_y = y & mask
                mask_x = mask_y ^ new_ans
                if mask_x in seen and y <= 2 * seen[mask_x]:
                    ans = new_ans
                    break
                # 即使会覆盖以前出现过的mask_x,也只会让结果更优
                # 因为x的值越大越好,我们可以保证x <= y,这只会更容易满足条件2.
                seen[mask_y] = y

        return ans

小结

这种算法结合了位运算和哈希表,有效地解决了在一定条件下求最大异或值的问题。它展示了如何在复杂问题中运用多种技术和方法。

你可能感兴趣的:(算法,leetcode,散列表,python)