Given a non-empty array of numbers, a0, a1, a2, … , an-1, where 0 ≤ ai < 231.
Find the maximum result of ai XOR aj, where 0 ≤ i, j < n.
Could you do this in O(n) runtime?
Example:
Input: [3, 10, 5, 25, 2, 8]
Output: 28
Explanation: The maximum result is 5 ^ 25 = 28.
转载于这里
思路:用字典树解决;将所有的数用二进制表示,如果一个树表示,则可用一颗深度为32的树表示,每棵树最多有两个儿子0和1.当根据数组中的数建好trie后,要找到两个数的最大异或。每个数都在这颗树中遍历,从这个数的最高位bit开始,如果trie树中在该层存在与bit不同的节点,说明结果sum的这一位应为1.然后,在该节点下,继续遍历。如果不存在这样的节点,说明sum在这一位应为0,接着往这一节点的子节点遍历。这种方式,一个num最多比较32次,不用和每个num都要异或一次。每次高位的比较都直接决定下一次的比较路径。时间复杂度:
O(n),n
为数组的大小
class Solution {
struct trie{
trie* son[2];
trie(){
memset(son,0,sizeof(son));
}
};
public:
int findMaximumXOR(vector<int>& nums) {
int n=nums.size();
if(!n) return 0;
//初始化trie
trie* root=new trie();
int i,k;
for(auto num:nums)
{
trie* curnode=root;
for(i=31;i>=0;--i)
{
int curbit=(num>>i)&1;
if(curnode->son[curbit]==NULL)
curnode->son[curbit]=new trie();
curnode=curnode->son[curbit];
}
}
//计算最大的xOR
int maxor=INT_MIN;
for(auto num:nums)
{
trie* curnode=root;
int sum=0;
for(i=31;i>=0;i--)
{
int curbit=(num>>i)&1;
if(curnode->son[curbit^1]!=NULL){
sum+=1<<i;
curnode=curnode->son[curbit^1];
}else
curnode=curnode->son[curbit];
}
maxor=max(maxor,sum);
}
return maxor;
}
};