Maximum XOR of Two Numbers in an Array--异或、字典树

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 ≤ ij < 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.

也是看了提示后才知道使用字典树来解决此题。

这里用二叉树来表示trie(网上有用数组来建字典树的,但没看懂),先把nums中的所有数插入到trie中,也就是建树的过程。一个nums[i]插入树中的时间为O(31),n个数的时间复杂度就为O(31n)。然后对于每个nums[i],在树中搜索与其异或值最大的那个nums[j]。过程如下:假设只有三位,比如要搜索的nums[0]==4==100,那么我们在搜索的时候就按011来搜,因为100^011最大。当然如果树中没有011,假如只有001,那么在搜到第二位时,没有1分支只有0分支,那么就只能走0分支了。搜索的时间复杂度也为O(31n)。

总的时间复杂度大概O(62n)。

代码如下:

class Solution {
public:
    struct Trie{
        Trie* child[2] = {NULL}; //child[0]左子树,代表0,child[1]右子树,代表1。
    };
    int findMaximumXOR(vector<int>& nums) {
        Trie* trie = new Trie;
        int i, temp, maxXor = INT_MIN, size = nums.size();
        //先建立字典树trie---O(32n)
        for(i = 0; i < size; ++i) 
            insert(trie, nums[i]);
        
        //遍历nums,对于每一个nums[i],都在trie中搜索与nums[i]异或结果最大的那个nums[j].搜索规则是按位取反搜索,即按相反的分支搜。O(32n)
        for(i = 0; i < size; ++i){
            temp = nums[i]^search(trie, nums[i]); 
            if(maxXor < temp) maxXor = temp;
        }
        return maxXor;
    }
    void insert(Trie* trie, int n){
        char bit;
        Trie* curNode = trie, *newNode;
        for(int i = 30; i >= 0; --i){
            bit = (n>>i)&1;
            if(curNode->child[bit]==NULL){
                newNode = new Trie;
                curNode->child[bit] = newNode;
            }
            curNode = curNode->child[bit];
        }
    }
    int search(Trie* trie, int n){ //返回数组nums中与n相异或结果最大的那个nums[j]
        char bit;
        int val = 0, POW = pow(2,30);
        Trie* curNode = trie;
        for(int i = 30; i >= 0; --i){
            bit = (n>>i)&1;
            if(curNode->child[1-bit]!=NULL){
                val += (1-bit)*POW;
                curNode = curNode->child[1-bit];
            }
            else{
                val += bit*POW;
                curNode = curNode->child[bit];
            }
            POW /= 2;
        }
        return val;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值