421. 数组中两个数的最大异或值
给你一个整数数组 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 = [14,70,53,83,49,91,36,80,92,51,66,70]
输出:127
提示:
1 <= nums.length <= 2 * 105
0 <= nums[i] <= 2的31次方 - 1
字典树
思路:可以将每个数变成最高31位的二进制数,建立字典树,为使异或值最大,应该尽可能找不一样的,如果该位为0先找1,该位为1先找0
cpp
class Solution {
public:
//记录某个id下下个数为0或者1的id
int a[200005*31][2];
//记录某个id代表的十进制数 是唯一的
int cnt[200005*31];
//按顺序赋予id,代表树的一个节点
int id=0;
int findMaximumXOR(vector<int>& nums) {
for(int i=0;i<nums.size();i++){
insert(nums[i]);
}
int res=0;
for(int i=0;i<nums.size();i++){
res = max(res,find(nums[i]));
}
return res;
}
//建树
void insert(int b){
int p=0;
for(int i=30;i>=0;i--){
int x=(b>>i)&1;//获得第i位的值
if(a[p][x]==0) a[p][x]=++id;//新建节点
p=a[p][x];
}
cnt[p]=b;//记录该节点的十进制数
}
//找树中和b异或的最大值
int find(int b){
int p=0;
int big=0;
for(int i=30;i>=0;i--){
int x=(b>>i)&1;
if(x==1){
if(a[p][0]!=0) p=a[p][0];
else if(a[p][1]!=0) p=a[p][1];
}
if(x==0){
if(a[p][1]!=0) p=a[p][1];
else if(a[p][0]!=0) p=a[p][0];
}
}
big=max(big,b^cnt[p]);
return big;
}
};