【字典树(前缀树) 异或 离线查询】1707. 与数组中元素的最大异或值

本文涉及知识点

字典树(前缀树) 位运算 异或 离线查询

LeetCode1707. 与数组中元素的最大异或值

给你一个由非负整数组成的数组 nums 。另有一个查询数组 queries ,其中 queries[i] = [xi, mi] 。
第 i 个查询的答案是 xi 和任何 nums 数组中不超过 mi 的元素按位异或(XOR)得到的最大值。换句话说,答案是 max(nums[j] XOR xi) ,其中所有 j 均满足 nums[j] <= mi 。如果 nums 中的所有元素都大于 mi,最终答案就是 -1 。
返回一个整数数组 answer 作为查询的答案,其中 answer.length == queries.length 且 answer[i] 是第 i 个查询的答案。
示例 1:
输入:nums = [0,1,2,3,4], queries = [[3,1],[1,3],[5,6]]
输出:[3,3,7]
解释:

  1. 0 和 1 是仅有的两个不超过 1 的整数。0 XOR 3 = 3 而 1 XOR 3 = 2 。二者中的更大值是 3 。
  2. 1 XOR 2 = 3.
  3. 5 XOR 2 = 7.
    示例 2:
    输入:nums = [5,2,4,6,6,3], queries = [[12,4],[8,1],[6,3]]
    输出:[15,-1,5]
    提示:
    1 <= nums.length, queries.length <= 105
    queries[i].length == 2
    0 <= nums[j], xi, mi <= 109

离线查询、字典树

indexs 记录 queries的下标。queries[index[i]][1] 升序。
for( i: indexs){
将小于等于mi的nums元素加到字典树。
y = 查询字典树和xi的最大异或值。
vRet[i] = y;
}

离线查询、字典树代码

核心代码

class C2BNumTrieNode
{
public:C2BNumTrieNode(){m_childs[0] = m_childs[1] = nullptr;}bool GetNot0Child(bool bFirstRight){auto ptr = m_childs[bFirstRight];if (ptr && (ptr->m_iNum > 0)){return bFirstRight;}return !bFirstRight;}int m_iNum = 0;C2BNumTrieNode* m_childs[2];
};template<class T = int, int iLeveCount = 31>
class C2BNumTrie
{
public:C2BNumTrie(){m_pRoot = new C2BNumTrieNode();}void  Add(T iNum){m_setHas.emplace(iNum);C2BNumTrieNode* p = m_pRoot;for (int i = iLeveCount - 1; i >= 0; i--){p->m_iNum++;bool bRight = iNum & ((T)1 << i);if (nullptr == p->m_childs[bRight]){p->m_childs[bRight] = new C2BNumTrieNode();}p = p->m_childs[bRight];}p->m_iNum++;}void Del(T iNum){auto it = m_setHas.find(iNum);if (m_setHas.end() == it){return;}m_setHas.erase(it);C2BNumTrieNode* p = m_pRoot;for (int i = iLeveCount - 1; i >= 0; i--){p->m_iNum--;bool bRight = iNum & ((T)1 << i);p = p->m_childs[bRight];}p->m_iNum--;}T MaxXor(T iNum){C2BNumTrieNode* p = m_pRoot;T iRet = 0;for (int i = iLeveCount - 1; i >= 0; i--){bool bRight = !(iNum & ((T)1 << i));bool bSel = p->GetNot0Child(bRight);p = p->m_childs[bSel];if (bSel == bRight){iRet |= ((T)1 << i);}}return iRet;}void Swap(C2BNumTrie<T, iLeveCount>& o) {swap(m_pRoot, o.m_pRoot);swap(m_setHas, o.m_setHas);}C2BNumTrieNode* m_pRoot;std::unordered_multiset<T> m_setHas;
};class Solution {
public:vector<int> maximizeXor(vector<int>& nums, vector<vector<int>>& queries) {const int n = nums.size();vector<int> indexs(queries.size());iota(indexs.begin(), indexs.end(), 0);sort(indexs.begin(), indexs.end(), [&](int i1, int i2) {return queries[i1][1] < queries[i2][1]; });sort(nums.begin(), nums.end(),std::greater<int>());C2BNumTrie trie;vector<int> ret(queries.size());for (int i : indexs) {while ((nums.size())&&(nums.back() <= queries[i][1])) {trie.Add(nums.back());nums.pop_back();}ret[i] = (nums.size()==n ) ? -1 :  trie.MaxXor(queries[i][0]);}return ret;}
};

测试用例

template<class T>
void Assert(const vector<T>& v1, const vector<T>& v2)
{if (v1.size() != v2.size()){assert(false);return;}for (int i = 0; i < v1.size(); i++){assert(v1[i] == v2[i]);}
}template<class T>
void Assert(const T& t1, const T& t2)
{assert(t1 == t2);
}int main()
{vector<int> nums;vector<vector<int>> queries;{Solution slu;nums = { 3 }, queries = { {2,2} };auto res = slu.maximizeXor(nums, queries);Assert({ -1 }, res);}{Solution slu;nums = { 2 }, queries = { {2,2} };auto res = slu.maximizeXor(nums, queries);Assert({ 0 }, res);}{Solution slu;nums = { 0,1,2,3,4 }, queries = { {3,1},{1,3},{5,6} };auto res = slu.maximizeXor(nums, queries);Assert({ 3,3,7 }, res);}{Solution slu;nums = { 5,2,4,6,6,3 }, queries = { {12,4},{8,1},{6,3} };auto res = slu.maximizeXor(nums, queries);Assert({ 15,-1,5 }, res);}
}

2023年4月版

class C2BNumTrieNode
{
public:
C2BNumTrieNode()
{
m_childs[0] = m_childs[1] = nullptr;
}
bool GetNot0Child(bool bFirstRight)
{
auto ptr = m_childs[bFirstRight];
if (ptr && ( ptr->m_iNum >0 ))
{
return bFirstRight;
}
return !bFirstRight;
}
int m_iNum = 0;
C2BNumTrieNode* m_childs[2] ;
};

template
class C2BNumTrie
{
public:
C2BNumTrie()
{
m_pRoot = new C2BNumTrieNode();
}
void Add(int iNum)
{
C2BNumTrieNode* p = m_pRoot;
for (int i = iLeveNum - 1; i >= 0; i–)
{
p->m_iNum++;
bool bRight = iNum & (1 << i);
if (nullptr == p->m_childs[bRight])
{
p->m_childs[bRight] = new C2BNumTrieNode();
}
p = p->m_childs[bRight];
}
p->m_iNum++;
}
C2BNumTrieNode* m_pRoot;

};
class Solution {
public:
vector maximizeXor(vector& nums, vector<vector>& queries) {
const int iBitNum =30;
std::sort(nums.begin(), nums.end());
vector indexs;
for (int i = 0; i < queries.size(); i++)
{
indexs.emplace_back(i);
}
std::sort(indexs.begin(), indexs.end(), [&](const int& i1, const int& i2)
{
return queries[i1][1] < queries[i2][1];
});
//std::priority_queue<int,vector,greater> queNums(nums.begin(), nums.end());
int iDoNums =0;
C2BNumTrie trie;
vector vRet(indexs.size());
for (int i = 0; i < indexs.size(); i++)
{
const int index = indexs[i];
const int iCur = queries[index][0];
const int iRev = iCur ^ ((1 << iBitNum)- 1);
const int iMax = queries[index][1];
while ((iDoNums < nums.size()) && (nums[iDoNums] <= iMax))
{
trie.Add(nums[iDoNums]);
iDoNums++;
}

		if (0 == trie.m_pRoot->m_iNum){vRet[index] = -1;continue;}auto p = trie.m_pRoot;int iSel = 0;for (int i = iBitNum - 1; i >= 0; i--){bool bRight = iRev & (1 << i);bool bSel  = p->GetNot0Child(bRight);p = p->m_childs[bSel];if (bSel){iSel |= (1 << i);}}			vRet[index] = iSel^iCur;}return vRet;
}

};

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

相关下载

想高屋建瓴的学习算法,请下载《喜缺全书算法册》doc版
https://download.csdn.net/download/he_zhidan/88348653

我想对大家说的话
《喜缺全书算法册》以原理、正确性证明、总结为主。
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/15612.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++ | Leetcode C++题解之第97题交错字符串

题目&#xff1a; 题解&#xff1a; class Solution { public:bool isInterleave(string s1, string s2, string s3) {auto f vector <int> (s2.size() 1, false);int n s1.size(), m s2.size(), t s3.size();if (n m ! t) {return false;}f[0] true;for (int i …

264 基于matlab的自适应语音盲分离

基于matlab的自适应语音盲分离&#xff0c;当a和b同时对着传声器A,B说话且传声器靠得很近时&#xff0c;传声器A,B会同时接受到a和b的声音&#xff0c;即a和b产生了混叠干扰&#xff0c;此时通过自适应语音盲分离系统可以将a,b的声音分离开&#xff0c;使得一个信道只有一个人的…

2024.05.25学习记录

1、面经复习&#xff1a; JS异步进阶、vue-react-diff、vue-router模式、requestldleCallback、React Fiber 2、代码随想录刷题、动态规划 3、组件库使用storybook

python抽取pdf中的参考文献

想将一份 pdf 论文中的所有参考文献都提取出来&#xff0c;去掉不必要的换行&#xff0c;放入一个 text 文件&#xff0c;方便复制。其引用是 ieee 格式的&#xff0c;形如&#xff1a; 想要只在引用序号&#xff08;如 [3]&#xff09;前换行&#xff0c;其它换行都去掉&…

VTK 数据处理:特征边提取

VTK 数据处理&#xff1a;特征边提取 VTK 数据处理&#xff1a;特征边提取原理实例 1&#xff1a;边界边提取实例 2&#xff1a;模型特征边提取实例 3&#xff1a;利用 vtkFeatureEdges 提取的边界补洞实例 4&#xff1a;利用 vtkFillHolesFilter 补洞 VTK 数据处理&#xff1a…

OC属性关键字和单例模式

OC的属性关键字和单例模式 文章目录 OC的属性关键字和单例模式单例模式基本创建重写allocWithZone方法的同时使用dispatch_once 属性和属性关键字property和synthesize&#xff0c;dynamic属性关键字atomic和nonatomicstrong和weakreadonly和readwritestrong和copy 单例模式 单…

MySQL--存储引擎

一、存储引擎介绍 1.介绍 存储引擎相当于Linux的文件系统&#xff0c;以插件的模式存在&#xff0c;是作用在表的一种属性 2.MySQL中的存储引擎类型 InnoDB、MyISAM、CSV、Memory 3.InnoDB核心特性的介绍 聚簇索引、事务、MVCC多版本并发控制、行级锁、外键、AHI、主从复制特…

Python | Leetcode Python题解之第112题路径总和

题目&#xff1a; 题解&#xff1a; class Solution:def hasPathSum(self, root: TreeNode, sum: int) -> bool:if not root:return Falseif not root.left and not root.right:return sum root.valreturn self.hasPathSum(root.left, sum - root.val) or self.hasPathSum…

关于在子线程中获取不到HttpServletRequest对象的问题

这篇文章主要分享一下项目里遇到的获取request对象为null的问题&#xff0c;具体是在登录的时候触发的邮箱提醒&#xff0c;获取客户端ip地址&#xff0c;然后通过ip地址定位获取定位信息&#xff0c;从而提示账号在哪里登录。 但是登录却发现获取request对象的时候报错了。 具…

Docker提示某网络不存在如何解决,添加完网络之后如何删除?

Docker提示某网络不存在如何解决&#xff1f; 创建 Docker 网络 假设现在需要创建一个名为my-mysql-network的网络 docker network create my-mysql-network运行容器 创建网络之后&#xff0c;再运行 mysqld_exporter 容器。完整命令如下&#xff1a; docker run -d -p 9104…

认识K8s集群的声明式资源管理方法

前言 Kubernetes 集群的声明式资源管理方法是当今云原生领域中的核心概念之一&#xff0c;使得容器化应用程序的部署和管理变得更加高效和可靠。本文将认识了解 Kubernetes 中声明式管理的相关理念、实际应用以及优势。 目录 一、管理方法介绍 1. 概述 2. 语法格式 2.1 管…

Spring Boot Interceptor(拦截器使用及原理)

之前的博客中讲解了关于 Spring AOP的思想和原理&#xff0c;而实际开发中Spring Boot对于AOP的思想的具体实现就是Spring Boot Interceptor。在 Spring Boot 应用程序开发中&#xff0c;拦截器&#xff08;Interceptor&#xff09;是一个非常有用的工具。它允许我们在 HTTP 请…

Redis可视化工具:Another Redis Desktop Manager下载安装使用

1.Github下载 github下载地址&#xff1a; Releases qishibo/AnotherRedisDesktopManager GitHub 2. 安装 直接双击exe文件进行安装 3. 连接Redis服务 先启动Redis服务&#xff0c;具体启动过程可参考&#xff1a; Windows安装并启动Redis服务端&#xff08;zip包&#xff09…

Golang | Leetcode Golang题解之第111题二叉树的最小深度

题目&#xff1a; 题解&#xff1a; func minDepth(root *TreeNode) int {if root nil {return 0}queue : []*TreeNode{}count : []int{}queue append(queue, root)count append(count, 1)for i : 0; i < len(queue); i {node : queue[i]depth : count[i]if node.Left …

FileZilla“服务器发回了不可路由的地址,使用服务器地址代替

问题&#xff1a;在宝塔创建的FTP无法使用&#xff0c;提示“服务器回应不可路由的地址。使用服务器地址代替 第一种解决办法&#xff1a;由于宝塔把FTP被动模式端口范围设置成了39000-40000&#xff0c;所以只需要把阿里云服务器上相应的端口范围开放即可。 第二种解决办法&am…

网络安全之安全协议浅谈

安全协议 安全协议概述安全协议分类IPSecIPSec安全协议IPSec架构IPSec封装模式AH协议ESP协议SET协议SET协议电子交易模型SET协议安全目标认证中心CA 安全协议概述 安全协议是信息交换安全的核心&#xff0c;它在网络不同层次上、针对不同应用&#xff0c;通过对各种密码学技术…

LiveGBS流媒体平台GB/T28181用户手册-云端录像:查看录像、列表视图、时间轴视图、下载、删除

LiveGBS流媒体平台GB/T28181用户手册-云端录像:查看录像、列表视图、时间轴视图、下载、删除 1、云端录像1.1、查看录像1.1.1、时间轴视图1.1.2、列表视图1.1.3、日期切换1.1.4、删除当天 1.2、录像计划1.2.1、录像计划列表1.2.2、编辑录像计划1.2.3、关联通道1.2.4、删除录像计…

解决在cmd里下载的库,但IDLE还是显示不存在的问题

原因一&#xff1a; 环境变量配置 首先&#xff0c;你需要确认你安装库的时候使用的Python环境是否和IDLE使用的Python环境是同一个。如果cmd中你使用的是系统路径下的Python&#xff0c;而IDLE使用的是另一个路径下的Python&#xff0c;那么你在cmd中下载的库&#xff0c;IDL…

存在重复元素 II[简单]

优质博文&#xff1a;IT-BLOG-CN 一、题目 给你一个整数数组nums和一个整数k&#xff0c;判断数组中是否存在两个不同的索引i和j&#xff0c;满足nums[i] nums[j]且abs(i - j) < k。如果存在&#xff0c;返回true&#xff1b;否则&#xff0c;返回false。 示例 1&#…