421. Maximum XOR of Two Numbers in an Array

Posted apanda009

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了421. Maximum XOR of Two Numbers in an Array相关的知识,希望对你有一定的参考价值。

Given a non-empty array of numbers, a0, a1, a2, … , an-1, where 0 ≤ ai < 231.

Find the maximum result of ai XOR aj, where 0 ≤ i, j < n.

Could you do this in O(n) runtime?

Example:

Input: [3, 10, 5, 25, 2, 8]

Output: 28

Explanation: The maximum result is 5 ^ 25 = 28.

这道题是一道典型的位操作Bit Manipulation的题目,我开始以为异或值最大的两个数一定包括数组的最大值,但是OJ给了另一个例子{10,23,20,18,28},这个数组的异或最大值是10和20异或,得到30。那么只能另辟蹊径,正确的做法是按位遍历,题目中给定了数字的返回不会超过231,那么最多只能有32位,我们用一个从左往右的mask,用来提取数字的前缀,然后将其都存入set中,我们用一个变量t,用来验证当前位为1再或上之前结果res,看结果和set中的前缀异或之后在不在set中,这里用到了一个性质,若a^b=c,那么a=b^c,因为t是我们要验证的当前最大值,所以我们遍历set中的数时,和t异或后的结果仍在set中,说明两个前缀可以异或出t的值,所以我们更新res为t,继续遍历,如果上述讲解不容易理解,那么建议自己带个例子一步一步试试,并把每次循环中set中所有的数字都打印出来,基本应该就能理解了,参见代码如下:

public class Solution {
    public int findMaximumXOR(int[] nums) {
        int mask = 0, max = 0;
        for (int i=31; i>=0; i--) {
            mask |= 1<<i;
            HashSet<Integer> prefixes = new HashSet<Integer>();
            for (int each : nums) {
                prefixes.add(each & mask); // reserve Left bits and ignore Right bits
            }
            int tmpMax = max | (1<<i);   
            //possible new max, for example: max right now is 11000, then tmpMax=11100, max is 11100, tmpMax is 11110
            for (int prefix : prefixes) {
                if (prefixes.contains(tmpMax^prefix)) 
                    max = tmpMax;
            }
        }
        return max;
    }
}

  

Solution 2: Trie, (未研究)

https://discuss.leetcode.com/topic/63207/java-o-n-solution-using-trie

https://discuss.leetcode.com/topic/64753/31ms-o-n-java-solution-using-trie

 

以上是关于421. Maximum XOR of Two Numbers in an Array的主要内容,如果未能解决你的问题,请参考以下文章

231. Power of Two

231 Power of Two 2的幂

231. Power of Two

Leetcode 231: Power of Two

位运算——Power of Two

LeetCode231. Power of Two