您的位置:首页 > 其它

【LeetCode-421】Maximum XOR of Two Numbers in an Array

2016-10-16 21:49 676 查看
Given a list of numbers, a[0], a[1], a[2], … , a[N-1], where 0 <= a[i] < 2^32. Find the maximum result of a[i] XOR a[j].

Could you do this in O(n) runtime?

Input: [3, 10, 5, 25, 2, 8]

Output: 28

题目 : 求一个数组中两两异或的最大值,要求时间复杂度是O(n)

当拿到这样一道题时,coder一般会想到使用暴力解决的方法,但是明显这不符合题目的时间复杂度要求,这就需要进一步来思索,是不是有其他方法。

经过一阵思考之后,想到了一种使用 Trie 这种数据结构来解决(如果你还不熟悉这种数据结构,赶快百度一下吧)。解决这个问题有三个步骤:

1.建立Trie : 将数组中的元素根据31个比特位(符号位忽略)保存到Trie中;

2.在Trie中寻找和元素x异或最大的数 :

例如 : x 的二进制表示为 :

0000 0000 0000 0000 0000 0000 0000 0101

那与x异或最大的数是 :

0111 1111 1111 1111 1111 1111 1111 1010;

3.遍历数组,找到最大的异或值;

下面是我的代码:

public int findMaximumXOR(int[] nums) {
if(nums == null || nums.length < 2){
return 0;
}
Node root = new Node();

for(int i : nums){
buildTrie(root, i);
}

int res = Integer.MIN_VALUE;
for(int i : nums){
int temp = findMostMatch(root, i);
res = temp > res ? temp : res;
}

return res;
}

//x与其他元素异或的最大值
private int findMostMatch(Node root, int x){
int res = 0;
Node temp = root;
for(int i = 30;i >= 0;i --){
int bit = x & (1 << i);
int flag = bit == 0 ? 0 : 1;
//每次都找与bit相反的分支(相反的不存在才寻找相同的)
if(temp.next[1 - flag] == null){
temp = temp.next[flag];
res += flag << i;
} else {
temp = temp.next[1 - flag];
res += (1 - flag) << i;
}
}

return res ^ x;
}

//创建Trie
private void buildTrie(Node root, int x){
Node temp = root;
for(int i = 30;i >= 0;i --){
int bit = x & (1 << i);
int flag = bit == 0 ? 0 : 1;

if(temp.next[flag] == null){
temp.next[flag] = new Node();
}

temp = temp.next[flag];
}
}

private static class Node {
Node[] next;

public Node(){
next = new Node[2];
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: