构造字典树解决异或问题

         二进制 与 树的结合,是最头疼的问题了,非常不想看,但是,解决这类问题,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;
}
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值