题目原文
Difficulty: Medium
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:
1 2 3 4 5
   | Input: [3, 10, 5, 25, 2, 8]
  Output: 28
  Explanation: The maximum result is 5 ^ 25 = 28.
   | 
 
解法:使用 Trie 树(前缀树)和分治法
时间复杂度 O(n)
根据题目描述,我们需要找到最大的异或值,异或代表了两个数的二进制的不同程度,且越高位越不一样,异或值就越大,由于是按位比较,所以使用 Trie 树来当做基础数据结构。
我们可以总结出以下几点:
- 因为整型的位数是固定的,排除第一位符号位,Trie 树的高度是常数的,即最高
32层(包括root) 
- 由于只有
0和1两个子节点,所以为了节省空间,可以使用二叉树的方式(或者数组和 HashMap 均可) 
- 由于是异或,前缀位如果相同,异或值都是 0,所以可以先找到第一个两个子节点都不为空的节点当做
root 

以此构建 Trie 树,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
   | class Solution {     class TrieNode {         int val;         TrieNode zero, one;         boolean isEnd;     }     class TrieTree {         TrieNode root;         public TrieTree() {             root = new TrieNode();         }         public void insert(int num) {             TrieNode cur = root;             int j = 1 << 30;             for (int i = 0; i < 31; i++) {                                  int b = (j & num) == 0 ? 0 : 1;                 if (b == 0 && cur.zero == null) {                     cur.zero = new TrieNode();                 }                 if (b == 1 && cur.one == null) {                     cur.one = new TrieNode();                 }                 cur = b == 0 ? cur.zero : cur.one;                 j >>= 1;             }             cur.isEnd = true;             cur.val = num;         }     }
      public int findMaximumXOR(int[] nums) {         if (nums == null || nums.length <= 1) {             return 0;         }         TrieTree tree = new TrieTree();         for (int n : nums) {             tree.insert(n);         }                  TrieNode cur = tree.root;         while (cur.one == null || cur.zero == null) {             cur = cur.zero != null ? cur.zero : cur.one;         }         return maxHelper(cur.one, cur.zero);
      }
      
 
 
 
 
 
 
      private int maxHelper(TrieNode one, TrieNode zero) {         if (one.isEnd && zero.isEnd) {             return one.val ^ zero.val;         }         if (one.zero == null) {             return maxHelper(one.one, zero.zero == null ? zero.one : zero.zero);         } else if (one.one == null) {             return maxHelper(one.zero, zero.one == null ? zero.zero : zero.one);         } else if (zero.zero == null) {             return maxHelper(one.zero, zero.one);         } else if (zero.one == null) {             return maxHelper(one.one, zero.zero);         } else {             return Math.max(maxHelper(one.one, zero.zero), maxHelper(one.zero, zero.one));         }     } }
  | 
 
本文同样发在了 LeetCode 讨论区