最暴力也最容易想到的是遍历数组中每一个数,计算与其他数的异或,并记录最大值,时间复杂度为O(n^2),oj上提交一定会超时,最多的解法是利用字典树,将数组中每个数字的二进制保存在树中,由于异或的规则是相同为0不同为1,要获得最大的异或值,则希望异或的结果又尽可能多的1,所以对数字进行取反后在字典树中寻找,记录每次寻找到最大的异或值,对于int数据,只要构建深度为32的字典树,搜索效率为O(32),每个数字搜索一遍,则算法的时间复杂度为O(32*n),用空间换时间,LeetCode题目代码如下:
class Solution {
public:
struct Trie {
vector<Trie*> child;
Trie():child(vector<Trie*>(2,NULL)){} // 两个分支不是0就是1
};
// 建立Trie树
void add(Trie *t,int x){
for(int i=31;i>=0;i--){
int bit = (x>>i)&1;
if(NULL == t->child[bit]){
t->child[bit] = new Trie();
}
t = t->child[bit];
}
}
int findXOR(Trie *t,int x){
int res = 0;
for(int i=31;i>=0;i--){
int bit = (x>>i)&1;
res = res<<1; // 移位1
if(t->child[!bit]){ // 异或大就要计算反的
t = t->child[!bit];
res = res+(!bit);
}
else {
t = t->child[bit];
res =res+bit;
}
}
return res;
}
int findMaximumXOR(vector<int>& nums) {
Trie *t = new Trie();
int Maxxor = 0;
for(int n:nums) add(t,n);
for(int n:nums){
int temp = findXOR(t,n);
Maxxor = max((temp^n),Maxxor);
}
return Maxxor;
}
};