数组中两个元素异或求最大值
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;
}
思路: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;
}
相关文章推荐
- Leetcode421. 找出数组中两个元素异或的最大值
- 求数组中两个元素差的最大值
- 求一个数组中两个元素的最大差值
- 421.Maximum XOR of Two Numbers in an Array 数组中异或值最大的两个数字
- 求数组中元素为另外两个元素和的最大元素
- 5-8: 输入一个5行、6列的数组,找出该数组中绝对值最大的元素,输出该元素及其两个下标值
- 两个数组的元素之和最大的前k项
- [LeetCode] Maximum XOR of Two Numbers in an Array 数组中异或值最大的两个数字
- 无序数组O(n)时间找到排序后的两个相邻元素使得他们之间的差最大
- 任意给定一整数数组,求两个元素之差的最大值和数组中出现次数最多的数
- 一个无序实数数组中的相邻两个元素的最大差值
- 给定一个数组input[] ,如果数组长度n为奇数,则将数组中最大的元素放到 output[] 数组 最中间的位置,如果数组长度n为偶数,则将数组中最大的元素放到 output[] 数组中间两个位置偏右的那个位置上
- 找出两个整型数组中的公共元素的最大值
- php 求一个无序数组经过排列后任意两个相邻元素之差的最大值(算法)
- 动态规划系列---求数组中两个元素差的最大值
- 说你有一个数组,其中第i个元素是第i天给定股票的价格。设计一个算法来找到最大的利润,最多可以完成两个交易。
- 每天学习一算法系列(5)(已知两个数组,数组里的元素有正有负,但是都是按照从小到大已经排好序,要求用尽可能小的时间复杂度编写一算法求出两个数组的最大交集)
- 数组内两个元素的最大差
- 求一个数组中满足一定条件的两个元素的最大差值
- 每天学习一算法系列(5)(已知两个数组,数组里的元素有正有负,但是都是按照从小到大已经排好序,要求用尽可能小的时间复杂度编写一算法求出两个数组的最大交集)