数组中两个数的最大异或值(字典树+贪心)
2021/5/16 10:55:15
本文主要是介绍数组中两个数的最大异或值(字典树+贪心),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
传送门
题目描述:
给你一个整数数组 nums ,返回 nums[i] XOR nums[j] 的最大运算结果,其中 0 ≤ i ≤ j < n 。
进阶:你可以在 O(n) 的时间解决这个问题吗?
思路:直接进阶,看了题解才想出来....
字典树贪心,循环遍历每个数,对每个数的30位二进制位倒着建树,在插入该数之前我们首先对以及建好的树
进行贪心,查找当前数能与之前数异或出的最大值,具体如何选:
定义x表示能异或出的最大值,
如果当前位置为1,则看已经建成的树的当前位置是否能选0,能选0就选0,x+=(1<<i),
不能选0,就只能选1,x不变,因为两个1异或为0,
如果当前位置为0,则判断树中该位置是否能选1,能选就x=x+(1<<i),反之就选0,x不变
可以贪心的原因:因为我们是倒着判断每一位的,即从高位到低位,如果高位能取1,就一定
是最好的选择。
AC代码:
const int maxn=200005; class Solution { public: int tree[maxn][2],tot; void insert(int x){ int now=0; for(int i=30;i>=0;i--){ if(tree[now][(x&(1<<i))!=0]){ now=tree[now][(x&(1<<i))!=0]; }else{ tree[now][(x&(1<<i))!=0]=++tot; now=tot; } } } int get(int x){ int now=0,ans=0; for(int i=30;i>=0;i--){//倒着贪心 if((x&(1<<i))!=0){ if(tree[now][0]){ ans+=(1<<i); now=tree[now][0]; }else { now=tree[now][1]; } }else{ if(tree[now][1]){ ans+=(1<<i); now=tree[now][1]; }else { now=tree[now][0]; } } } return ans; } int findMaximumXOR(vector<int>& nums) { if(nums.size()==1)return 0; insert(nums[0]);//先插入第一个数 int res=0; for(int i=1;i<nums.size();i++){ res=max(get(nums[i]),res);//找出当前数和之前的数异或结果的最大值get(x); insert(nums[i]); } return res; } };
这篇关于数组中两个数的最大异或值(字典树+贪心)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-07-04TiDB 资源管控的对撞测试以及最佳实践架构
- 2024-07-03万字长文聊聊Web3的组成架构
- 2024-07-02springboot项目无法注册到nacos-icode9专业技术文章分享
- 2024-06-26结对编程到底难不难?答案在这里
- 2024-06-19《2023版Java工程师》课程升级公告
- 2024-06-15matplotlib作图不显示3D图,怎么办?
- 2024-06-1503-Loki 日志监控
- 2024-06-1504-让LLM理解知识 -Prompt
- 2024-06-05做软件测试需要懂代码吗?
- 2024-06-0514-ShardingSphere的分布式主键实现