最大的异或(剑指offer-67)

原题链接

题目描述

给定一个整数数组 nums ,返回 nums[i] XOR nums[j] 的最大运算结果,其中 0 ≤ i ≤ j < n

示例1

输入:nums = [3,10,5,25,2,8]
输出:28
解释:最大运算结果是 5 XOR 25 = 28.

示例2

输入:nums = [0]
输出:0

示例3

输入:nums = [2,4]
输出:6

示例4

输入:nums = [8,10,2]
输出:10

示例5

输入:nums = [14,70,53,83,49,91,36,80,92,51,66,70]
输出:127

思路1

暴力做法,两层循环,分别求出两两数组的异或值,求最大值,时间复杂度O(n^2),代码略。

思路2

对于某个数,既然要找和他异或的最大值,所以就是要找尽可能多的位数与它不同的数,因为位数不同异或值为1,相同为0。所以我们可以将每个数字的二进制下的每个数位都保存下来,然后查找。
我们可以采用字典树(前缀树),一个结点对应一个二进制数位。
因为整型是4个字节,就是32位,所以长度都是一样的,就不需要isWord字段来判断是不是最后一个数位了。
因为二进制只有0和1,所以表示子节点的数组的大小设为2就可以。

完整代码

class Solution {
    private TrieNode root;
    class TrieNode{
        TrieNode[] children;
        public TrieNode(){
            children = new TrieNode[2];
        }
    }
    public int findMaximumXOR(int[] nums) {
        build(nums);
        int maxx = 0;
        for(int num : nums){
            TrieNode node = root;
            int curMax = 0;
            for(int i = 31; i >= 0; i--){
				//从高位开始建树,比如(num>>31)&1,那么得到的就是最高位
                int bit = (num >> i) & 1;
                if(node.children[1 - bit] != null){
                    node = node.children[1 - bit];
                    curMax = (curMax << 1) + 1;
                }else{
                    node = node.children[bit];
                    curMax = (curMax << 1);
                }
            }
            maxx = Math.max(maxx, curMax);
        }
        return maxx;
    }
    private void build(int[] nums){
        root = new TrieNode();
        for(int num : nums){
        TrieNode node = root;
            for(int i = 31; i >= 0; i--){
                int bit = (num >> i) & 1;
                if(node.children[bit] == null){
                    node.children[bit] = new TrieNode();
                }
                node = node.children[bit];
            }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值