字典树的应用:求数组中异或最大的两个数

求数组中异或最大的两个数,题目参考

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 child;
	Trie():child(vector(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& 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;
    }
};


你可能感兴趣的:(leetcode,算法-字典树)