您的位置:首页 > 其它

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

2016-09-28 22:56 411 查看
给一个整数数组,求数组中两个元素异或的最大值.

思路: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;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  位运算 trie
相关文章推荐