【单调栈】【二分查找】LeetCode: 2454.下一个更大元素 IV

news2024/12/25 12:47:16

作者推荐

【动态规划】【广度优先】LeetCode2258:逃离火灾

本文涉及的基础知识点

二分查找算法合集
单调栈

题目

给你一个下标从 0 开始的非负整数数组 nums 。对于 nums 中每一个整数,你必须找到对应元素的 第二大 整数。
如果 nums[j] 满足以下条件,那么我们称它为 nums[i] 的 第二大 整数:
j > i
nums[j] > nums[i]
恰好存在 一个 k 满足 i < k < j 且 nums[k] > nums[i] 。
如果不存在 nums[j] ,那么第二大整数为 -1 。
比方说,数组 [1, 2, 4, 3] 中,1 的第二大整数是 4 ,2 的第二大整数是 3 ,3 和 4 的第二大整数是 -1 。
请你返回一个整数数组 answer ,其中 answer[i]是 nums[i] 的第二大整数。
示例 1:
输入:nums = [2,4,0,9,6]
输出:[9,6,6,-1,-1]
解释:
下标为 0 处:2 的右边,4 是大于 2 的第一个整数,9 是第二个大于 2 的整数。
下标为 1 处:4 的右边,9 是大于 4 的第一个整数,6 是第二个大于 4 的整数。
下标为 2 处:0 的右边,9 是大于 0 的第一个整数,6 是第二个大于 0 的整数。
下标为 3 处:右边不存在大于 9 的整数,所以第二大整数为 -1 。
下标为 4 处:右边不存在大于 6 的整数,所以第二大整数为 -1 。
所以我们返回 [9,6,6,-1,-1] 。
示例 2:
输入:nums = [3,3]
输出:[-1,-1]
解释:
由于每个数右边都没有更大的数,所以我们返回 [-1,-1] 。
参数范围
1 <= nums.length <= 105
0 <= nums[i] <= 109

单调栈找更大的元素,有序映射寻找第二个更大元素

时间复杂度:O(nlogn)。枚举更大(第二个更大)元素,时间复杂度O(n)。有序映射的插入,时间复杂度O(logn)。

变量解释

staNoMax记录所有没有比它大的元素的元素所有
mValueIndexmValueIndex,记录所有找到更大的元素,但没找到第二个更大元素的元素所有。键:值;值:索引。

二分查找优化

staNoMax是降序,当新增元素x的时候,所有小于x的元素都会出栈,所以x的前面如果有元素,则一定大于等于x。
由于staNoMax是降序,所以当x2大于等于x时,前面元素也大于x,所以无需继续查找。
** 注意**:
mValueInde先删除,否则增加的元素,马上删除。当前元素成了更大元素和下一个更大元素。

代码

核心代码

class Solution {
public:
vector secondGreaterElement(vector& nums) {
stack staNoMax;
std::multimap<int,int> mValueIndex;
vector vRet(nums.size(), -1);
for (int i = 0; i < nums.size(); i++)
{
while (mValueIndex.size() && (mValueIndex.begin()->first < nums[i]))
{
vRet[mValueIndex.begin()->second] = nums[i];
mValueIndex.erase(mValueIndex.begin());
}
while (staNoMax.size() && (nums[staNoMax.top()] < nums[i]))
{
mValueIndex.emplace(nums[staNoMax.top()],staNoMax.top());
staNoMax.pop();
}
staNoMax.emplace(i);
}
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> nums;
	
	{
		Solution slu;
		nums = { 2, 4, 0, 9, 6 };
		auto res = slu.secondGreaterElement(nums);
		Assert(vector<int>{9, 6, 6, -1, -1}, res);
	}
	{
		Solution slu;
		nums = { 3,3 };
		auto res = slu.secondGreaterElement(nums);
		Assert(vector<int>{ -1, -1}, res);
	}
	{
		Solution slu;
		nums = { 272, 238, 996, 406, 763, 164, 102, 948, 217 ,760,609,700,848 };
		auto res = slu.secondGreaterElement(nums);
		Assert(vector<int>{406, 406, -1, 948, 848, 217, 217, -1, 609, -1, 848, -1, -1}, res);
	}
	
	//CConsole::Out(res);
}

优化

mValueIndex新增元素之前,mValueIndex中的元素一定大于等于nums[i],否则被删除了。新增加到mValueIndex的元素一定小于nums[i]。故之前增加的元素一定大于本次增加。 本次增加的是按升序加的,可以放到缓存中,按反顺序加入。这样:有序映射就优化成了栈。

class Solution {
public:
	vector<int> secondGreaterElement(vector<int>& nums) {
		stack<int> staNoMax,staNoMax2;
		vector<int> vRet(nums.size(), -1);
		vector<int> vBuf;
		for (int i = 0; i < nums.size(); i++)
		{
			while (staNoMax2.size() && (nums[staNoMax2.top()] < nums[i]))
			{
				vRet[staNoMax2.top()] = nums[i];
				staNoMax2.pop();
			}
			while (staNoMax.size() && (nums[staNoMax.top()] < nums[i]))
			{
				vBuf.emplace_back(staNoMax.top());
				staNoMax.pop();
			}
			staNoMax.emplace(i);
			for (auto it = vBuf.rbegin(); it != vBuf.rend(); ++it)
			{
				staNoMax2.emplace(*it);
			}
			vBuf.clear();
		}
		return vRet;
	}
};

2023年3月版 二分查找

bool GreaterPairInt(const std::pair<int, int>& p,int iData )
{
return p.first > iData ;
}

class Solution {
public:
vector secondGreaterElement(vector& nums) {
m_c = nums.size();
//vLeftFirstLess[i] i是它的下一个更大数
vector<vector> vLeftFirstLess(m_c);
{
vector<pair<int, int>> vStack;
for (int i = m_c - 1; i >= 0; i–)
{
int iNum = std::lower_bound(vStack.begin(), vStack.end(), nums[i], GreaterPairInt) - vStack.begin();
if (iNum > 0)
{
const int iFristGreaterIndex = vStack[iNum - 1].second;;
vLeftFirstLess[iFristGreaterIndex].push_back(i);
}
while (vStack.size() && (nums[i] >= vStack.back().first))
{
vStack.pop_back();
}
vStack.emplace_back(nums[i], i);
}
}
vector vRet(m_c, -1);
{
vector<pair<int, int>> vStack;
for (int i = m_c - 1; i >= 0; i–)
{
for (auto& it : vLeftFirstLess[i])
{
int iNum = std::lower_bound(vStack.begin(), vStack.end(), nums[it], GreaterPairInt) - vStack.begin();
if (iNum > 0)
{
const int iFristGreaterIndex = vStack[iNum - 1].second;;
vRet[it] = nums[iFristGreaterIndex];
}
}
while (vStack.size() && (nums[i] >= vStack.back().first))
{
vStack.pop_back();
}
vStack.emplace_back(nums[i], i);
}
}
return vRet;
}
int m_c;
};

2023年9月版

class Solution {
public:
vector secondGreaterElement(vector& nums) {
m_c = nums.size();
stack sta;
std::priority_queue<std::pair<int, int>, vector<std::pair<int, int>>, greater<>> minHeap;
vector vRet(m_c, -1);
for (int i = 0; i < m_c; i++)
{
const int& n = nums[i];
while (minHeap.size() && (minHeap.top().first < n))
{
vRet[minHeap.top().second] = n;
minHeap.pop();
}
while (sta.size() && (nums[sta.top()] < n))
{
minHeap.emplace(nums[sta.top()], sta.top());
sta.pop();
}
sta.emplace(i);
}
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/1303670.html

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

相关文章

极狐GitLab CI/CD 变量黑魔法之预定义变量

目录 预定义变量 commit 相关 Job 相关 Pipeline 相关 镜像仓库有关 极狐GitLab CI/CD 变量是指一系列的环境变量&#xff0c;用来帮助我们控制 CI/CD Job 或 Pipeline 的行为&#xff0c;存储一些可以复用的信息&#xff0c;避免在 .gitlab-ci.yml 中形成硬编码。 极狐G…

2024年湖北省高空作业证报名考试取证周期些许夸张

2024年湖北省高空作业证报名考试取证周期些许夸张 湖北省高空作业证报名考试取证周期些许夸张&#xff0c;快的话一周左右也是可以的。湖北省高空作业证一般指的都是湖北省应急管理厅下发的高空作业“特种作业操作证”。主要分为&#xff1a;高处安装拆除维修作业和登高架设作…

基于laravel、vue开发的医院手术麻醉管理系统源码,自主版权,二开快捷。

医院手术麻醉管理系统源码&#xff0c;自主版权&#xff0c;二开快捷&#xff0c;有演示 技术架构&#xff1a;PHP、 js 、mysql、laravel、vue2 手术麻醉临床信息管理系统是数字化手段应用于手术过程中的重要组成部分&#xff0c;用数字形式获取并存储手术相关信息&#xff…

Mybatis之自定义映射resultMap

学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰。各位小伙伴&#xff0c;如果您&#xff1a; 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持&#xff0c;想组团高效学习… 想写博客但无从下手&#xff0c;急需…

【愚公系列】2023年12月 HarmonyOS教学课程 015-ArkUI组件(Radio)

&#x1f3c6; 作者简介&#xff0c;愚公搬代码 &#x1f3c6;《头衔》&#xff1a;华为云特约编辑&#xff0c;华为云云享专家&#xff0c;华为开发者专家&#xff0c;华为产品云测专家&#xff0c;CSDN博客专家&#xff0c;CSDN商业化专家&#xff0c;阿里云专家博主&#xf…

【51单片机系列】文字取模软件使用

软件链接&#xff1a;https://pan.baidu.com/s/1k-ND9vJReW_KHMWx8uwpcQ?pwdgz8w 提取码&#xff1a;gz8w 双击打开软件&#xff0c;选择【基本操作】->【新建图像】&#xff0c;设置图像的宽度和高度为8。点击确定后将在显示窗口出现一个8x8的白色格子&#xff0c;类似于…

jupyter报错KeyError: ‘icosapent‘

指的是未找到关键词 代码想在一个pkl文件里找到关键词对应的值&#xff0c;然后报了这个错 尝试直接双击pkl文件&#xff0c;显示&#xff1a; 这个意思不是说这个文件保存失败&#xff0c;也不是说这个文件是坏的&#xff0c;而是jupyter无法读取这个格式。 换成pycharm运行…

Chrome谷歌浏览器安装VUE调试插件

访问gitee的vue-devtools 并下载 gitee地址&#xff1a;https://gitee.com/zhang_banglong/vue-devtools 也可以访问git的地址&#xff1a;https://github.com/vuejs/devtools 解压&#xff0c;放到自己的目录下 打开控制面板&#xff08;管理员&#xff09;&#xff0c;进入…

STM32超声波——HC_SR04

文章目录 一.超声波图片二.时序图三.超声波流程四.单位换算五.取余计算六.换算距离七.超声波代码 一.超声波图片 测量距离&#xff1a;2cm——400cm 二.时序图 (1).以下时序图要先提供一个至少10us的脉冲触发信号&#xff0c;告诉单片机我准备好了&#xff0c;然后该超声波…

WordPress如何搭建多站点

这边之前有讲到过wordpress站中站&#xff08;栏目站&#xff09;建站教程&#xff0c;同样的也有讲到过WordPress开启多站点配置&#xff0c;两种方法都是用来搭建子站点的&#xff0c;而开启多站点的方式不同于普通搭建站中站&#xff0c;多站点配置开启&#xff0c;是可以实…

进程的同步和异步、进程互斥

一、进程同步和异步 同步&#xff08;Synchronous&#xff09;&#xff1a; 同步指的是程序按照顺序执行&#xff0c;一个操作完成后才能进行下一个操作。在多进程或多线程的环境中&#xff0c;同步意味着一个进程&#xff08;或线程&#xff09;在执行某个任务时&#xff0c;…

AttributeError: module ‘scrapy‘ has no attribute ‘Filed‘

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

02-Nacos和Eureka的区别与联系

Nacos和Eureka的区别 联系 Nacos和Eureka整体结构类似: 都支持服务注册, 服务拉取, 采用心跳方式对服务提供者做健康监测的功能 区别 Nacos支持服务端主动检测服务提供者状态: 临时实例采用心跳模式,非临时实例采用主动检测模式但对服务器压力比较大(不推荐) 心跳模式: 服务…

使用NCNN在华为M5部署MobileNet-SSD

一、下载ncnn-android-vulkan ncnn-android-vulkan.zip 文件是一个压缩文件&#xff0c;其中包含了 ncnn 框架在 Android 平台上使用 Vulkan 图形库加速的相关文件和代码。 在 Android 平台上&#xff0c;ncnn 框架可以利用 Vulkan 的并行计算能力来进行神经网络模型的推理计…

智能优化算法应用:基于混合蛙跳算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于混合蛙跳算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于混合蛙跳算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.混合蛙跳算法4.实验参数设定5.算法结果6.…

西工大网络空间安全学院计算机系统基础实验二(phase_2下——漫漫深夜过后的黎明!!!)

内存地址内存地址中的数注释指向这块内存的寄存器0xffffd0e8函数phase_2的栈帧0xffffd0e40xffffd0f4函数phase_2的栈帧0xffffd0e00x5655b7b0函数phase_2的栈帧0xffffd0dc0x565566ca函数read_six_numbers的返回地址&#xff0c;函数phase_2的栈帧0xffffd0d80x5655af64旧%ebx的值…

Spark邂逅大数据

系列文章目录 送书第一期 《用户画像&#xff1a;平台构建与业务实践》 送书活动之抽奖工具的打造 《获取博客评论用户抽取幸运中奖者》 送书第二期 《Spring Cloud Alibaba核心技术与实战案例》 送书第三期 《深入浅出Java虚拟机》 送书第四期 《AI时代项目经理成长之道》 …

perl脚本中使用eval函数执行可能有异常的操作

perl脚本中有时候执行的操作可能会引发异常&#xff0c;为了直观的说明&#xff0c;这里举一个json反序列化的例子&#xff0c;脚本如下&#xff1a; #! /usr/bin/perl use v5.14; use JSON; use Data::Dumper;# 读取json字符串数据 my $json_str join(, <DATA>); # 反…

.Net6.0 Microsoft.AspNetCore.Http.Abstractions 2.20 已弃用

您想要升级 Microsoft.AspNetCore.Http.Abstractions 包&#xff0c;您需要注意以下几点&#xff1a; Microsoft.AspNetCore.Http.Abstractions 包在 ASP.NET Core 2.2 版本后已经被标记为过时&#xff0c;因为它已经被包含在 Microsoft.AspNetCore.App 框架引用中12。因此&am…

分配栈空间的三种方式(基于适配qemu的FreeRTOS分析)

1、定义全局的数组 定义的全局数组属于bss段&#xff0c;相当于把bss段的一部分作为栈空间&#xff0c;栈空间的大小就是数组的大小如果把栈空间放在bss段&#xff0c;则在bss段清零时会多清零一段地址空间 2、在链接脚本中指定 用链接脚本在所有段的后面增加stack段&#xff…