map|二分查找|离线查询|LeetCode:2736最大和查询

news2024/11/16 9:46:20

本文涉及的基础知识点

二分查找算法合集

题目

给你两个长度为 n 、下标从 0 开始的整数数组 nums1 和 nums2 ,另给你一个下标从 1 开始的二维数组 queries ,其中 queries[i] = [xi, yi] 。
对于第 i 个查询,在所有满足 nums1[j] >= xi 且 nums2[j] >= yi 的下标 j (0 <= j < n) 中,找出 nums1[j] + nums2[j] 的 最大值 ,如果不存在满足条件的 j 则返回 -1 。
返回数组 answer ,其中 answer[i] 是第 i 个查询的答案。
示例 1:
输入:nums1 = [4,3,1,2], nums2 = [2,4,9,5], queries = [[4,1],[1,3],[2,5]]
输出:[6,10,7]
解释:
对于第 1 个查询:xi = 4 且 yi = 1 ,可以选择下标 j = 0 ,此时 nums1[j] >= 4 且 nums2[j] >= 1 。nums1[j] + nums2[j] 等于 6 ,可以证明 6 是可以获得的最大值。
对于第 2 个查询:xi = 1 且 yi = 3 ,可以选择下标 j = 2 ,此时 nums1[j] >= 1 且 nums2[j] >= 3 。nums1[j] + nums2[j] 等于 10 ,可以证明 10 是可以获得的最大值。
对于第 3 个查询:xi = 2 且 yi = 5 ,可以选择下标 j = 3 ,此时 nums1[j] >= 2 且 nums2[j] >= 5 。nums1[j] + nums2[j] 等于 7 ,可以证明 7 是可以获得的最大值。
因此,我们返回 [6,10,7] 。
示例 2:
输入:nums1 = [3,2,5], nums2 = [2,3,4], queries = [[4,4],[3,2],[1,1]]
输出:[9,9,9]
解释:对于这个示例,我们可以选择下标 j = 2 ,该下标可以满足每个查询的限制。
示例 3:
输入:nums1 = [2,1], nums2 = [2,3], queries = [[3,3]]
输出:[-1]
解释:示例中的查询 xi = 3 且 yi = 3 。对于每个下标 j ,都只满足 nums1[j] < xi 或者 nums2[j] < yi 。因此,不存在答案。
参数范围
nums1.length == nums2.length
n == nums1.length
1 <= n <= 105
1 <= nums1[i], nums2[i] <= 109
1 <= queries.length <= 105
queries[i].length == 2
xi == queries[i][1]
yi == queries[i][2]
1 <= xi, yi <= 109

离线查询、值降序map

时间复杂度😮(nlogn)。
按xi的降序对queries的索引排序。

变量解析

maxHeap记录所有的nums1[j]和nums2[j],nums1[j]大的在堆顶
ySum记录所有nums[j]大于当前xi的nums2[j]和nums1[j]+nums2[j],键升序,值降序。如果 nums2[j1] <= nums2[j2]且nums1[j1]+nums2[j1] <=nums1[j2]+nums2[j2]。则j1被j2淘汰了。
it[it,ySum.m_map.end()) 中的元素,全部大于xi和yi,由于值是降序,所有第一个值就是答案。

代码

核心代码

template<class _Kty,class _Ty,bool bValueDdes,bool bOutSmallKey> 
class COrderValueMap 
{
public:
	void Add (_Kty key, _Ty value)
	{
		if (bOutSmallKey)
		{
			if (bValueDdes)
			{
				AddOutSmall(key, value, std::less_equal<_Ty>(), std::greater_equal<_Ty>());
			}
			else
			{
				AddOutSmall(key, value, std::greater_equal<_Ty>(), std::less_equal<_Ty>());
			}
		}
		else 
		{
			if (bValueDdes)
			{
				AddNotOutSmall(key, value, std::greater_equal<_Ty>(), std::less_equal<_Ty>());
			}
			else
			{
				AddNotOutSmall(key, value, std::less_equal<_Ty>(), std::greater_equal<_Ty>());
			}
		}
	};
	std::map<_Kty, _Ty> m_map;
protected:
	template<class _Pr1, class _Pr2>
	void AddOutSmall(_Kty key, _Ty value, _Pr1 pr1, _Pr2 pr2)
	{
		auto it = m_map.lower_bound(key);
		if ((m_map.end() != it) && pr1(it->second, value))
		{
			return;//被旧值淘汰
		}
		auto ij = it;
		while (it != m_map.begin())
		{
			--it;
			if (pr2(it->second, value))
			{
				it = m_map.erase(it);
			}
		}
		m_map[key] = value;
	}
	template<class _Pr1, class _Pr2>
	void AddNotOutSmall(_Kty key, _Ty value, _Pr1 pr1,_Pr2 pr2 )
	{
		auto it = m_map.upper_bound(key);
		if ((m_map.begin() != it) && pr1(std::prev(it)->second, value))
		{
			return;//被淘汰
		}
		auto ij = it;
		for (; (m_map.end() != ij) && pr2(ij->second, value); ++ij);
		m_map.erase(it, ij);
		m_map[key] = value;
	};
	
};
class Solution {
public:
	vector<int> maximumSumQueries(vector<int>& nums1, vector<int>& nums2, vector<vector<int>>& queries) {
		vector<int> indexs(queries.size());
		iota(indexs.begin(), indexs.end(), 0);
		sort(indexs.begin(), indexs.end(), [&](const int i1, const int i2) {return queries[i1][0] > queries[i2][0]; });
		priority_queue<pair<int, int>> maxHeap;
		for (int i = 0; i < nums1.size(); i++)
		{
			maxHeap.emplace(nums1[i], nums2[i]);
		}
		COrderValueMap<int, int, false, true> ySum;
		vector<int> vRet(queries.size(), -1);
		for (const auto i : indexs)
		{
			while (maxHeap.size() && (maxHeap.top().first >= queries[i][0]))
			{
				ySum.Add(maxHeap.top().second, maxHeap.top().first + maxHeap.top().second);
				maxHeap.pop();
			}
			auto it = ySum.m_map.lower_bound(queries[i][1]);
			if (ySum.m_map.end() != it)
			{
				vRet[i] = it->second;
			}
		}
		return vRet;
	}
};

测试用例

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> nums1, nums2;
	vector<vector<int>> queries;
	{
		Solution slu;		
		nums1 = { 4,3,1,2 }, nums2 = { 2,4,9,5 }, queries = { {4,1},{1,3},{2,5} };
		auto res = slu.maximumSumQueries(nums1,nums2,queries);
		Assert(vector<int>{6, 10, 7}, res);
	}
	{
		Solution slu;
		nums1 = { 3,2,5 }, nums2 = { 2,3,4 }, queries = { {4,4},{3,2},{1,1} };
		auto res = slu.maximumSumQueries(nums1, nums2, queries);
		Assert(vector<int>{9, 9, 9}, res);
	}
	{
		Solution slu;
		nums1 = { 2,1 }, nums2 = { 2,3 }, queries = { {3,3} };
		auto res = slu.maximumSumQueries(nums1, nums2, queries);
		Assert(vector<int>{-1}, res);
	}
}

2023年6月代码

class CMaxLineTreeMap
{
public:
CMaxLineTreeMap(int iArrSize) :m_iArrSize(iArrSize)
{
}
//iIndex 从0开始
void Modify(int iIndex, int iValue)
{
Modify(1, 1, m_iArrSize, iIndex + 1, iValue);
}
//iNeedQueryLeft iNeedQueryRight 从0开始
int Query(const int iNeedQueryLeft, const int iNeedQueryRight)
{
return Query(1, 1, m_iArrSize, iNeedQueryLeft + 1, iNeedQueryRight + 1);
}
protected:
int Query(const int iTreeNodeIndex, const int iRecordLeft, const int iRecordRight, const int iNeedQueryLeft, const int iNeedQueryRight)
{
if ((iNeedQueryLeft <= iRecordLeft) && (iNeedQueryRight >= iRecordRight))
{
return m_mData[iTreeNodeIndex];
}
const int iMid = (iRecordLeft + iRecordRight) / 2;
int iRet = 0;
if (iNeedQueryLeft <= iMid)
{
iRet = Query(iTreeNodeIndex * 2, iRecordLeft, iMid, iNeedQueryLeft, iNeedQueryRight);
}
if (iNeedQueryRight > iMid)
{
iRet = max(iRet, Query(iTreeNodeIndex * 2 + 1, iMid + 1, iRecordRight, iNeedQueryLeft, iNeedQueryRight));
}
return iRet;
}
void Modify(int iTreeNodeIndex, int iLeft, int iRight, int iIndex, int iValue)
{
if (iLeft == iRight)
{
m_mData[iTreeNodeIndex] = max(m_mData[iTreeNodeIndex],iValue);
return;
}
const int iMid = (iLeft + iRight) / 2;
if (iIndex <= iMid)
{
Modify(iTreeNodeIndex * 2, iLeft, iMid, iIndex, iValue);
}
else
{
Modify(iTreeNodeIndex * 2 + 1, iMid + 1, iRight, iIndex, iValue);
}
m_mData[iTreeNodeIndex] = max(m_mData[iTreeNodeIndex * 2], m_mData[iTreeNodeIndex * 2 + 1]);
}
const int m_iArrSize;
std::unordered_map<int,int> m_mData;
};

class Solution {
public:
vector maximumSumQueries(vector& nums1, vector& nums2, vector<vector>& queries) {
m_c = queries.size();
vector indexs;
for (int i = 0; i < m_c; i++)
{
indexs.emplace_back(i);
}
std::sort(indexs.begin(), indexs.end(), [&queries](const int&i1, const int& i2)
{
return queries[i1][1] > queries[i2][1];
});
std::multimap<int, std::pair<int, int>> m_Num2ToNum1Sum;
for (int i = 0; i < nums2.size(); i++)
{
m_Num2ToNum1Sum.emplace(nums2[i], std::make_pair(nums1[i], nums1[i] + nums2[i]));
}
vector vRet(m_c);
auto it = m_Num2ToNum1Sum.rbegin();
const int iMaxValue = 1000 * 1000 * 1000;
CMaxLineTreeMap lineTree(iMaxValue+1);
for (int index = 0; index < indexs.size(); index++)
{
const int i = indexs[index];
const auto& que = queries[i];
while ((it != m_Num2ToNum1Sum.rend()) && (it->first >= que[1]))
{
lineTree.Modify(it->second.first, it->second.second);
it++;
}
vRet[i] = lineTree.Query(que[0], iMaxValue);
if (0 == vRet[i])
{
vRet[i] = -1;
}
}
return vRet;
}
int m_c;
};

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步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.coloradmin.cn/o/1309933.html

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

相关文章

css3 clip-path剪切图片

大致看了一下&#xff0c;反正以后用到就慢慢调吧 剪切四个角 clip-path: polygon(14px 0, calc(100% - 14px) 0, 100% 14px, 100% calc(100% - 14px), calc(100% - 14px) 100%, 14px 100%, 0 calc(100% - 14px), 0 14px); 三角形 clip-path: polygon(50% 0,0 100%, 100% 100…

工业级以太网交换机的功能介绍

随着互联网技术的迅猛发展&#xff0c;工业以太网在工业通信领域中发挥着重要作用。在整个工业通信行业中&#xff0c;工业以太网交换机作为关键的通信设备&#xff0c;具有非常重要的功能。那么&#xff0c;什么是工业以太网交换机呢&#xff0c;它有哪些功能呢&#xff1f; …

山西电力市场日前价格预测【2023-12-15】

1.日前价格预测 预测说明&#xff1a; 如上图所示&#xff0c;预测明日&#xff08;2023-12-15&#xff09;山西电力市场全天平均日前电价为279.14元/MWh。其中&#xff0c;最高日前电价为380.47元/MWh&#xff0c;预计出现在00:45。最低日前电价为181.13元/MWh&#xff0c;预…

Linux----1、初始Linux

# 初识Linux # 一、计算机资源介绍 计算机资源分为2 部分&#xff1a;硬件资源、软件资源 硬件&#xff1a; 一般硬件是指计算机的物理组成&#xff0c;由真实&#xff08;看得见&#xff0c;摸得着&#xff09;的设备组成的 软件&#xff1a; 软件一般是指应用程序&#x…

运筹学经典问题(六):设施选址问题

问题描述 设施选址问题&#xff08;Facility Location Problem, FLP&#xff09;也成选址-分配问题&#xff0c;是企业面临的一类重要问题&#xff1a;在哪里建造设施&#xff1f;建造多少&#xff1f;以及将哪些客户分配给哪些设施去服务&#xff1f; 以物流业的航空站点选…

被带偏的中国云计算,重归正途

文 | 智能相对论 作者 | 叶远风 阿里云战略聚焦公共云&#xff0c;对整个云计算市场而言都是一场自我审视。 从市场背景、行业发展、中外对比等多个方面&#xff0c;业界舆论给出了大量详实的数据分析&#xff0c;已经对阿里云为什么要聚焦公共云有了结论&#xff0c;这里不…

【学习笔记】V8垃圾回收策略

V8 V8是一款主流的JavaScript执行引擎V8采用即时编译,速度比较快V8内存设限,64位操作系统中上限为1.5G,32位系统中不超过800M V8垃圾回收策略 采用分代回收的思想内存分为新生代\老生代针对不同对象采用不同算法 v8常用的GC算法: 分代回收、空间复制、标记清除、标记整理、…

docker-compose 单机容器编排

dockerfile---yml文件 docker-compose需要用到 yml文件 yml文件是什么&#xff1f; 是一种标记语言&#xff0c;以竖列的形式展示序列化的数据格式&#xff0c;可读性高&#xff0c;类似于json格式。语法简单。 YAML通过缩进来表示数据结构&#xff0c;连续的项目用 - 减号来表…

JS基础之变量对象

JS基础之变量对象 变量对象基础变量对象全局上下文函数上下文执行过程进入执行上下文代码执行思考题 变量对象 基础 当JavaScript代码执行一段可执行代码&#xff08;executable code&#xff09;时&#xff0c;会创建对应的执行上下文&#xff08;execution context&#xff…

什么是SEO优化

什么是SEO&#xff0c;百度其实就有答案&#xff0c;只是回答的很基础&#xff0c;说的都是基础概念&#xff0c;没有具体的体现在里面&#xff0c;SEO除了基础概念&#xff0c;还要有相应的构架&#xff0c;不然怎么弄都是一场空而已。 关于什么是SEO的文章导读&#xff1f; 1…

伦敦金收盘线应用有技巧

伦敦金的收盘线的绘制方式相当简单&#xff0c;其实也就是MT4中折线图的画法&#xff0c;我们可以在走势图以金价为纵坐标&#xff0c;而以时间为横坐标&#xff0c;然后将每一日的收盘价位值沿着横坐标一一的连接起来&#xff0c;就形成了伦敦金价的收盘线图。 利用线条简单的…

深入浅出讲解半桥栅极驱动器IC FAN7382MX

FAN7382MX是单片高端栅极驱动器IC,可以驱动最高在 600V 下运行的 MOSFET 和 IGBT。安森美的高电压工艺和共模干扰抑制技术提供了高压侧驱动器在高 dv/dt 干扰情况下的稳定运行。先进的电平转换电路可针对 VBS 15V 允许最高 VS -9.8 V&#xff08;典型值&#xff09;的高压侧门…

【Python】部署Rabbitmq消息队列实现生产和消费

原文作者&#xff1a;我辈李想 版权声明&#xff1a;文章原创&#xff0c;转载时请务必加上原文超链接、作者信息和本声明。 文章目录 前言一、基础的生产者消费者二、ACK消息确认机制三、类的写法1.新建MyRabbitMQ.py文件2.基础RabiitMQ3.发布订阅4.多次执行RabiitMQ_生产 四、…

Cannot find cache named ‘‘ for Builder Redis

当引入 Redissson 时&#xff0c;springCache 缓存机制失效 原因&#xff1a;springCache 默认使用本地缓存 Redisson 使用redis 缓存 最后都转成redis了。。。 总感觉哪不对 两者居然不共存

SU渲染受到电脑性能影响大吗?如何提高渲染速度

一般3d设计师们在进行设计工作前都需要提供一台高配电脑&#xff0c;那么你这知道su渲染对电脑要求高吗&#xff1f;电脑带不动su怎么解决&#xff1f;su对电脑什么配件要求高&#xff1f;今天这篇文章就详细为大家带来电脑硬件对su建模渲染的影响&#xff0c;以及su渲染慢怎么…

学习深度强化学习---第3部分----RL蒙特卡罗相关算法

文章目录 3.1节 蒙特卡罗法简介3.2节 蒙特卡罗策略评估3.3节 蒙特卡罗强化学习3.4节 异策略蒙特卡罗法 本部分视频所在地址&#xff1a;深度强化学习的理论与实践 3.1节 蒙特卡罗法简介 在其他学科中的蒙特卡罗法是一种抽样的方法。 如果状态转移概率是已知的&#xff0c;则是…

Axure的流程图/泳道图以及自定义元件库的使用

目录 1.ProcessOn的介绍 2.流程图以及泳道图的介绍 2.1流程图 2.2流程图的特点 2.3泳道图 2.4泳道图的特点 2.5流程图跟泳道图的优缺点 2.5.1优点&#xff1a; 2.5.2缺点&#xff1a; 2.6流程图的使用 2.7流程图的案列 2.8泳道图的使用 3.自定义元件库 4.门诊流程…

【Bug修复】秒杀服务器异常,轻松恢复网站访问--从防火墙到Docker服务的全面解析

&#xff08;秒杀方案&#xff09;服务器异常&#xff1a;connection is closed by foreign host… 月初部署了一个私人项目到服务器上&#xff0c;刚开始还能用&#xff0c;用了不到两天报了上面的错误&#xff1a;connection is closed by foreign host… &#x1f33a;问题描…

Echarts多图表动态更新示例

前端框架(html、echarts、jquery) <!DOCTYPE html> <html><head><meta charset"utf-8"><title>echarts多图表动态更新示例</title><script src"jquery.min.js"></script><script type"text/java…

java.lang.IllegalArgumentException: Could not resolve placeholder XXX‘ in value

问题描述 使用Springcloudalibaba的nacos作为配置中心&#xff0c;服务启动时报错&#xff1a; java.lang.IllegalArgumentException: Could not resolve placeholder XXX‘ in value java.lang.IllegalArgumentException: Param ‘serviceName’ is illegal, serviceName is …