字典樹的應用:求數組中異或最大的兩個數

求數組中異或最大的兩個數,題目參考

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;
    }
};


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章