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

来源:互联网 发布:分布式数据库的优势 编辑:程序博客网 时间:2024/06/05 03:15

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];        }    }
2 0