题目
给定一个非空数组,数组中元素为 a0, a1, a2, … , an-1,其中 0 ≤ ai < 231 。
找到 ai 和aj 最大的异或 (XOR) 运算结果,其中0 ≤ i, j < n 。
你能在O(n)的时间解决这个问题吗?
示例:
输入: [3, 10, 5, 25, 2, 8]
输出: 28
解释: 最大的结果是 5 ^ 25 = 28.
代码
class Solution {
public:
int findMaximumXOR(vector<int>& nums) {
int res=0;
int mask=0;//mask是用来获得数组中的数的前缀的掩码
for(int i=31;i>=0;i--){
mask|=(1<<i);
set<int> masked;
pair<set<int>::iterator,bool> ret;
for(int j=0;j<nums.size();j++){
ret=masked.insert(mask&nums[j]);
}
int temp=res|(1<<i);
for(set<int>::iterator maskedit=masked.begin();maskedit!=masked.end();maskedit++){
if(masked.find(temp^(*maskedit))!=masked.end()){
res=temp;
break;
}
}
}
return res;
}
};
总结
这道题是位运算中比较有难度的,看了一篇公众号文章里写的方法后才会。
这道题的关键是:
1. 异或运算的"交换性",也就是如果a^b=c,那么a^c=b和b^c=a都成立,理解这一点后才可以用假设某一位是1的方法对数组中的元素做筛选。(也可以这样想,位运算就是二进制中不进位的加法)
2. 二进制的数越高位是1,那么这个数越大。
3. 理解如何使用前缀,也就是代码中的mask,锁定异或值最大的那两个数。
详细讲解的链接:
https://mp.weixin.qq.com/s/mWB-LeERXF5d1FViWz8uNA