leetcode
leetcode 2501 ~ 2550
找出强数对的最大异或值 II

找出强数对的最大异或值 II

难度:

标签:

题目描述

You are given a 0-indexed integer array nums. A pair of integers x and y is called a strong pair if it satisfies the condition:

  • |x - y| <= min(x, y)

You need to select two integers from nums such that they form a strong pair and their bitwise XOR is the maximum among all strong pairs in the array.

Return the maximum XOR value out of all possible strong pairs in the array nums.

Note that you can pick the same integer twice to form a pair.

 

Example 1:

Input: nums = [1,2,3,4,5]
Output: 7
Explanation: There are 11 strong pairs in the array nums: (1, 1), (1, 2), (2, 2), (2, 3), (2, 4), (3, 3), (3, 4), (3, 5), (4, 4), (4, 5) and (5, 5).
The maximum XOR possible from these pairs is 3 XOR 4 = 7.

Example 2:

Input: nums = [10,100]
Output: 0
Explanation: There are 2 strong pairs in the array nums: (10, 10) and (100, 100).
The maximum XOR possible from these pairs is 10 XOR 10 = 0 since the pair (100, 100) also gives 100 XOR 100 = 0.

Example 3:

Input: nums = [500,520,2500,3000]
Output: 1020
Explanation: There are 6 strong pairs in the array nums: (500, 500), (500, 520), (520, 520), (2500, 2500), (2500, 3000) and (3000, 3000).
The maximum XOR possible from these pairs is 500 XOR 520 = 1020 since the only other non-zero XOR value is 2500 XOR 3000 = 636.

 

Constraints:

  • 1 <= nums.length <= 5 * 104
  • 1 <= nums[i] <= 220 - 1

代码结果

运行时间: 187 ms, 内存: 22.2 MB


/*
题目思路:
1. 使用Java Stream API,首先生成所有可能的强数对。
2. 计算每个强数对的异或值。
3. 找出异或值的最大值。
*/

import java.util.*;
import java.util.stream.*;

public class Solution {
    public int maxStrongPairXOR(int[] nums) {
        return IntStream.range(0, nums.length)
                .boxed()
                .flatMap(i -> IntStream.range(i, nums.length)
                        .filter(j -> Math.abs(nums[i] - nums[j]) <= Math.min(nums[i], nums[j]))
                        .mapToObj(j -> nums[i] ^ nums[j]))
                .max(Integer::compareTo)
                .orElse(0);
    }
}

解释

方法:

此题解采用了排序和位操作的方法来寻找最大的异或值。首先,对数组进行排序以便后续的二分查找。主要的策略是从最高位开始尝试设置当前异或结果的每一位(从高到低),检查是否存在有效的强数对能够支持这一位的设置。使用一个辅助函数highestBit来确定最大数值的最高有效位。然后在此位上,从后向前遍历数组,对于每个数,确定其潜在的强数对区间,并使用二分查找在有效区间内寻找合适的强数对。若找到,则更新当前最大异或值ans并缩小后续搜索的范围。

时间复杂度:

O(n log n)

空间复杂度:

O(n)

代码细节讲解

🦆
在判断强数对的有效性时,为什么使用的条件是`|x - y| <= min(x, y)`,这个条件是如何保证强数对的定义满足的?
此条件确保两数x和y的差值不超过它们中的较小者。这意味着y最多是x的两倍减一(即y <= 2x - 1),这是因为如果y大于2x-1,差值|y-x|将大于x,不满足条件。这个条件防止了差值过大,确保两数在数量级上相近,从而可以视为强数对。
🦆
题解中提到使用二分查找来确定强数对的存在,具体在二分查找过程中如何确定一个数对(x, y)满足强数对的条件?
在二分查找中,我们通过设置lowNum和highNum来定义搜索范围,这两个值分别代表了在当前位设置下,可能与x形成强数对的y值的最小和最大界限。通过不断调整左右边界(left和right),检查中间值mid是否在这个范围内,如果找到,则表明存在满足强数对条件的y值。
🦆
在更新最大异或值`ans`时,为什么选择在找到满足条件的强数对后直接与当前位的值`x`进行或操作?这样的操作有什么特定的意义或优势?
当在某位上找到满足条件的强数对时,这意味着在这一位上可以安全地将ans的相应位从0设置为1(通过与x进行或操作),因为这保证了在此位上ans不会丢失潜在的最大值。这种操作确保了每找到一个更高的有效位,ans都能尽可能大地增加,从而达到最大异或值。
🦆
题解中提到,在处理每一位的时候都可能更新尾指针`tail`,请问更新尾指针的目的是什么?这样做如何影响算法的效率?
更新尾指针tail的目的是缩小搜索的范围,提高效率。当在某一位找到了符合条件的强数对时,后续的搜索就可以限制在当前找到的数的位置之前,因为更高位的数已经不再可能有更大的贡献。这样做通过减少不必要的比较和搜索,加快了算法的执行速度。

相关问题