求數組中異或最大的兩個數,題目參考
LeetCode:https://leetcode.com/problems/maximum-xor-of-two-numbers-in-an-array/description/
hdoj :http://acm.hdu.edu.cn/showproblem.php?pid=4825
最暴力也最容易想到的是遍歷數組中每一個數,計算與其他數的異或,並記錄最大值,時間複雜度爲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)){}
};
void add(Trie *t,int x){
for(int i=31;i>=0;i--){
int bit = (x>>i)&1;
if(!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;
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;
}
};