二进制 与 树的结合,是最头疼的问题了,非常不想看,但是,解决这类问题,dfs它不给力啊!!无奈,逼着自己学了。
思路:
一、dfs 两两异或 找到最大值不就ok吗?结果超时— —!这么多的数是要闹哪样!
二、构建字典树
尽可能能多的保留高位1-------这样的结果才能保证最大。
前缀树【字典树】的构造是:左节点存储0,右节点存储1.
取数与当前字典树比较时,每一个节点尽可能的不相同。
代码部分:
part1----创建树节点
part2----构建前缀树
part3----比较判断求 ans
int compareNode(int num){
Tree*cur=root;
ans=0;
for(int k= Hightnum;k>=0;--k){
int bit=(num>>k)&1;//当前 计算 k 位置 上的 二进制为 是啥
if(bit==0){//如果是0,找 1,看1存不存在
if(cur->right){//如果1 存在,计算一下值
cur=cur->right;
ans=ans*2+1;
}
else{//如果1不存在,说明没开辟,只能找 0
cur=cur->left;
ans=ans*2;
}
}
else{
if(cur->left){
cur=cur->left;
ans=ans*2+1;
}
else{
cur=cur->right;
ans=ans*2;
}
}
}
return ans;
}
总体代码:
struct Tree
{
int val;
Tree*left;
Tree*right;
Tree(int x):val(x),left(nullptr),right(nullptr){};
};
class Solution {
public:
Tree*root=new Tree(0);
const int Hightnum=30;
int ans;
void addTreeNode(int num){
Tree*cur=root;
for(int k=Hightnum;k>=0;--k){
int bit=(num>>k)&1;//表示第 k 位上的二进制数
if(bit==0){
if(!cur->left)cur->left=new Tree(0);//如果当前节点的左节点没有开辟
cur=cur->left;//更新当前的cur节点
}
else{
if(!cur->right)cur->right=new Tree(1);
cur=cur->right;
}
}
}
int compareNode(int num){
Tree*cur=root;
ans=0;
for(int k= Hightnum;k>=0;--k){
int bit=(num>>k)&1;
if(bit==0){
if(cur->right){
cur=cur->right;
ans=ans*2+1;
}
else{
cur=cur->left;
ans=ans*2;
}
}
else{
if(cur->left){
cur=cur->left;
ans=ans*2+1;
}
else{
cur=cur->right;
ans=ans*2;
}
}
}
return ans;
}
int findMaximumXOR(vector<int>& nums) {
int x=0;
for(int i=1;i<nums.size();i++){
addTreeNode(nums[i-1]);
compareNode(nums[i]);
x=max(x,ans);
}
return x;
}
};