其他分享
首页 > 其他分享> > 最大的异或(剑指offer-67)

最大的异或(剑指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];
            }
        }
    }
}

标签:node,offer,int,nums,TrieNode,异或,67,bit,children
来源: https://blog.csdn.net/Ego12138/article/details/120640879