面试算法67:最大的异或

题目

输入一个整数数组(每个数字都大于或等于0),请计算其中任意两个数字的异或的最大值。例如,在数组[1,3,4,7]中,3和4的异或结果最大,异或结果为7。

分析

整数的异或有一个特点,如果两个相同数位异或的结果是0,那么两个相反的数位异或的结果为1。如果想找到某个整数k和其他整数的最大异或值,那么尽量找和k的数位不同的整数。
因此,这个问题可以转化为查找的问题,而且还是按照整数的二进制数位进行查找的问题。需要将整数的每个数位都保存下来。前缀树可以实现这种思路,前缀树的每个节点对应整数的一个数位,路径对应一个整数。

public class Test {
    public static void main(String[] args) {
        int[] dict = {1, 3, 4, 7};
        System.out.println(findMaximumXOR(dict));
    }

    static class TrieNode {
        public TrieNode[] children;

        public TrieNode() {
            children = new TrieNode[2];
        }
    }

    private static TrieNode buildTrie(int[] nums) {
        TrieNode 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];
            }
        }

        return root;
    }

    public static int findMaximumXOR(int[] nums) {
        TrieNode root = buildTrie(nums);
        int max = 0;
        for (int num : nums) {
            TrieNode node = root;
            int xor = 0;
            for (int i = 31; i >= 0; i--) {// 从高位开始比较
                int bit = (num >> i) & 1;
                if (node.children[1 - bit] != null) {// 存在和bit不一样的bit
                    xor = (xor << 1) + 1;
                    node = node.children[1 - bit];
                }
                else {
                    xor = xor << 1;
                    node = node.children[bit];
                }
            }

            max = Math.max(max, xor);
        }
        return max;
    }
}

你可能感兴趣的:(算法,算法,java,数据结构)