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

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值