题目:421
题意:给你一个整数数组 nums ,返回 nums[i] XOR nums[j]
的最大运算结果,其中 0 ≤ i ≤ j < n 。
题解:
核心思想: 在位运算异或运算符中,x = ai⊕ aj 等价于 ai= x ⊕ aj ,由于数的范围在0~231-1范围内,所以每一次从二进制的角度选取最大的x。
方法一: 哈希表,具体而言,保存数组中每一个数的前k位,从第30位开始,每一次选取数组中是否存在使得当前x可以满足的解;详细思路可以看代码进行理解。
class Solution {
public:
int findMaximumXOR(vector<int>& nums) {
int high_bit = 30;
int x = 0;
for(int k = high_bit; k >= 0; --k){
unordered_set<int> seen;
// 保存所有的前k个数到哈希表中
for(int num : nums){
seen.insert(num >> k);
}
// 假设存在对应的x
x = (x << 1) + 1;
bool found = false;
// 枚举数组,判断是否存在相应的ai、aj
for(int num : nums){
if(seen.count(x ^ (num >> k))){
found = true;
break;
}
}
// 如果不存在,第k位应该为0
if(!found){
x -= 1;
}
}
return x;
}
};
方法二: 使用前缀树枚举,具体而言,将数组中每个元素看成一个长度为31的字符串进行查询。由于这个过程对每一个ai都进行枚举了,当遍历完所有字符串就得到了最终结果。