数组中两个元素异或求最大值

给一个整数数组,求数组中两个元素异或的最大值.


思路:naive的做法是两两异或求最大值,时间复杂度为O(n*n),但是还有一种O(n)的解法,利用字典树Trie来实现.

其思路是利用数组中的每个元素二进制表示形式建一棵树,我看到网上大多数解法都开了太大的数组空间,不知道为什么,但是我觉得没有必要.只要用现有的数组元素二进制值建一棵深度为33的树即可,从根到叶子结点的路径就代表了一个元素.然后再对数组中每一个元素取反之后到Trie中去搜索最大的异或值,为什么要取反呢?因为取反之后在查找Trie的时候如果当前匹配的话,那么就说明当前这一位异或之后是为1的,我们就可以继续沿着这个分支走下去.如果不匹配说明异或之后当前这位是为0,并且这个分支为空,所以我们只能走另外一个分支.时间复杂度为O(32*n),也就是O(n)

代码如下:

/*************************************************************************
	> File Name: XorMax.cpp
	> Author: Maoting Ren
	> Mail: mren@g.clemson.edu
	> Created Time: Wed 28 Sep 2016 02:42:22 AM EDT
 ************************************************************************/

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

struct Trie
{
    vector<Trie*> child;
    Trie(): child(vector<Trie*>(2, NULL)){}
};

void add(int x, Trie* root)
{
    for(int i = 31; i >= 0; i--)
    {
        int bit = (x>>i)&1;
        if(!root->child[bit]) root->child[bit] = new Trie();
        root = root->child[bit];
    }
}

int search(int x, Trie* root)
{
    int ans = 0;
    for(int i = 31; i >= 0; i--)
    {
        int bit = (x>>i)&1;
        ans = ans<<1;
        if(root->child[bit]) ans++, root = root->child[bit];
        else root = root->child[!bit];
    }    
    return ans;
}

int main()
{
    Trie *root = new Trie();
    vector<int> vec{1, 2, 4, 8};
    for(int i = 0; i < (int)vec.size(); i++) add(vec[i], root);
    int ans = 0;
    for(int i = 0; i < (int)vec.size(); i++) 
        ans =  max(ans, search(~vec[i], root));
    cout << ans << endl;
    return 0;
}








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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值