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

最暴力也最容易想到的是遍历数组中每一个数,计算与其他数的异或,并记录最大值,时间复杂度为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;  
    }  
};  
    原文作者:Trie树
    原文地址: https://blog.csdn.net/mandagod/article/details/79581352
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞