Description
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.
Solution
Trie, time O(n), space O(n)
题意还是很明白的,找到两个数,二进制表达差的越多越好(大概这个意思)。但是怎么达到O(n)复杂度的确是个问题。遍历数组,对于每个i,找到和它差的最多的j?但这样就是O(n ^ 2)的复杂度啊。仔细想来可以用Trie来表示整个array,然后对于每一个i,只需要常数时间就能找到对应的j了。
注意要边搜索边累加XOR,否则到最后在计算i ^ j的话会TLE……
class Solution {
public int findMaximumXOR(int[] nums) {
if (nums == null || nums.length < 2) {
return 0;
}
// build Trie
TrieNode root = new TrieNode();
for (int n : nums) {
TrieNode pre = root;
for (int i = 31; i >= 0; --i) {
int bit = (n >> i) & 1;
if (pre.children[bit] == null) {
pre.children[bit] = new TrieNode();
}
pre = pre.children[bit];
}
}
// search Trie
int maxXOR = Integer.MIN_VALUE;
for (int n : nums) {
TrieNode pre = root;
int xor = 0;
for (int i = 31; i >= 0; --i) {
int bit = (n >> i) & 1;
if (pre.children[bit ^ 1] != null) {
pre = pre.children[bit ^ 1];
xor += 1 << i; // add to xor
} else {
pre = pre.children[bit];
}
}
maxXOR = Math.max(maxXOR, xor);
}
return maxXOR;
}
class TrieNode {
TrieNode[] children;
public TrieNode() {
children = new TrieNode[2];
}
}
}