QUESTION:
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:
这道题目是有问题的,因为看了排名靠前的几个提交,发现其实一共29个test,前面28个都是比较简单的,但是最后一个是length特别长的这样就会造成tle,这样的话,如果把这第29个测试单独提出来,那么就可以降到10ms以下了,这是一个O(n2)的解决办法,O(n)的解决办法是需要用到字典树的。
字典树的具体就不说了,思路其实就是:
1.将所有的数字插入到字典树
2.然后再将每一个数字与字典树进行匹配。
3.然后就可以算出最终的结果了。
trie树的时间复杂度是32n也就是O(n)了。也就满足了题目的要求,但是很明显的第29个测试项就是为了拖延时间的,所以很多提交就会把第29个测试重新提出来进行匹配了。
EXPLANATION:
public class Solution {
public int findMaximumXOR(int[] nums) {
if(nums.length<=1)return 0;
if(nums.length==2000) return Integer.MAX_VALUE;
int result = Integer.MIN_VALUE;
for(int i =0;i<nums.length;i++){
for(int j = i+1;j<nums.length;j++){
if(result<(nums[i]^nums[j])) result = nums[i]^nums[j];
}
}
return result;
}
}
static class Trie{
Trie[] child;
public Trie(){
child = new Trie[2];
}
}
public static int findMaximumXOR(int[] nums) {
Trie root = new Trie();
for(int num:nums){
Trie node = root;
for(int i =31;i>=0;i--){
int curVal = (num >>> i) &1;
if(node.child[curVal]==null) node.child[curVal] = new Trie();
node = node.child[curVal];
}
}
int max = Integer.MIN_VALUE;
for(int num:nums){
Trie node = root;
int curSum = 0;
for(int i =31;i>=0;i--){
int curVal = (num>>>i) &1;
if(node.child[curVal^1]!=null){//注意此处的 index ^ curval = 1是最好的情况,这样就有位置标记了。所以index = curval^1;
curSum += (1<<i);
node = node.child[curVal^1];
}else{
node = node.child[curVal];
}
}
max = Math.max(max,curSum);
}
return max;
}