题目描述
给定一个整数数组 nums ,返回 nums[i] XOR nums[j] 的最大运算结果,其中 0 ≤ i ≤ j < n
示例1
输入:nums = [3,10,5,25,2,8]
输出:28
解释:最大运算结果是 5 XOR 25 = 28.
示例2
输入:nums = [0]
输出:0
示例3
输入:nums = [2,4]
输出:6
示例4
输入:nums = [8,10,2]
输出:10
示例5
输入:nums = [14,70,53,83,49,91,36,80,92,51,66,70]
输出:127
思路1
暴力做法,两层循环,分别求出两两数组的异或值,求最大值,时间复杂度O(n^2),代码略。
思路2
对于某个数,既然要找和他异或的最大值,所以就是要找尽可能多的位数与它不同的数,因为位数不同异或值为1,相同为0。所以我们可以将每个数字的二进制下的每个数位都保存下来,然后查找。
我们可以采用字典树(前缀树),一个结点对应一个二进制数位。
因为整型是4个字节,就是32位,所以长度都是一样的,就不需要isWord字段来判断是不是最后一个数位了。
因为二进制只有0和1,所以表示子节点的数组的大小设为2就可以。
完整代码
class Solution {
private TrieNode root;
class TrieNode{
TrieNode[] children;
public TrieNode(){
children = new TrieNode[2];
}
}
public int findMaximumXOR(int[] nums) {
build(nums);
int maxx = 0;
for(int num : nums){
TrieNode node = root;
int curMax = 0;
for(int i = 31; i >= 0; i--){
//从高位开始建树,比如(num>>31)&1,那么得到的就是最高位
int bit = (num >> i) & 1;
if(node.children[1 - bit] != null){
node = node.children[1 - bit];
curMax = (curMax << 1) + 1;
}else{
node = node.children[bit];
curMax = (curMax << 1);
}
}
maxx = Math.max(maxx, curMax);
}
return maxx;
}
private void build(int[] nums){
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];
}
}
}
}