力扣2935. 找出强数对的最大异或值
题目概述
题目编号:2935
题目难度:困难
相关标签:数组, 排序, 位运算
给定一个整数数组 nums
,任务是找出其中可以形成的所谓“强数对”的最大异或值。强数对定义为一对整数 (x) 和 (y),满足 |x - y| ≤ \leq ≤ min(x, y)。
示例分析
-
示例 1
输入:nums = [1,2,3,4,5]
输出:7
分析:数组中的强数对及其异或值有多种组合,其中3 XOR 4 = 7
是最大的。 -
示例 2
输入:nums = [10,100]
输出:0
分析:仅有(10, 10)
和(100, 100)
两个强数对,它们的异或值均为 0。 -
示例 3
输入:nums = [500,520,2500,3000]
输出:1020
分析:最大异或值来自500 XOR 520 = 1020
。
解题思路
算法关键在于找到使异或值最大化的数对。首先,对数组进行排序,以便后续操作。主要思路是从最高位开始,检查是否存在两个数使得该位为 1,同时满足强数对条件。
- 使用掩码(
mask
)来逐位检查。 - 通过位运算和哈希表(
seen
)来快速判断是否存在满足条件的数对。 - 掩码用于保留数的前缀部分,以便对每个位的影响进行评估。
代码解析
- 排序:首先对
nums
排序,以简化强数对的确定。 - 位运算:使用位运算来逐步构建最大的异或值。
- 哈希表:使用哈希表来存储和快速检索数对。
- 掩码运算:掩码用于保留数字的高位部分,以检查每个位的贡献。
完整代码
class Solution:def maximumStrongPairXor(self, nums: List[int]) -> int:nums.sort()mask = 0ans = 0hb = max(nums).bit_length()for i in range(hb, -1, -1):mask |= 1 << inew_ans = ans | (1 << i)"""如果要使得第i位为1,,要满足两个条件1.存在mask_x ^ mask_y = new_ans2.存在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 & maskmask_x = mask_y ^ new_ansif mask_x in seen and y <= 2 * seen[mask_x]:ans = new_ansbreak# 即使会覆盖以前出现过的mask_x,也只会让结果更优# 因为x的值越大越好,我们可以保证x <= y,这只会更容易满足条件2.seen[mask_y] = yreturn ans
小结
这种算法结合了位运算和哈希表,有效地解决了在一定条件下求最大异或值的问题。它展示了如何在复杂问题中运用多种技术和方法。