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

作者推荐

【动态规划】【广度优先】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.mzph.cn/news/215226.shtml

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

相关文章

音视频技术开发周刊 | 323

每周一期&#xff0c;纵览音视频技术领域的干货。 新闻投稿&#xff1a;contributelivevideostack.com。 Meta牵头组建开源「AI复仇者联盟」&#xff0c;AMD等盟友800亿美元力战OpenAI英伟达 超过50家科技大厂名校和机构&#xff0c;共同成立了全新的人工智能联盟。以开源为旗号…

RocketMQ的架构是什么样的❓

RocketMQ&#xff0c;作为一款强大的分布式消息中间件&#xff0c;广泛应用于各种大规模分布式系统中&#xff0c;为异步消息通信提供了可靠的解决方案。本文将深入探讨RocketMQ的核心组件&#xff0c;包括Producer、Broker、Consumer和NameServer&#xff0c;以及它们在整个架…

高中物理电学总结之稳恒电流篇

高中物理电学总结之稳恒电流篇 电流电流的定义对电流的微观分析 电阻欧姆定律电阻的串并联电阻定律 电源的电动势电源电动势 闭合电路欧姆定律闭合电路闭合电路欧姆定律 电流做功与焦耳定律电流做功电功率焦耳定律电源效率 电表改装 电流 电流的定义 电解质溶液中的自由电荷是…

ACwing算法备战蓝桥杯——Day30——树状数组

定义&#xff1a; 树状数组是一种数据结构&#xff0c;能将对一个区间内数据进行修改和求前缀和的这两种操作的最坏时间复杂度降低到O(logn); 实现所需变量 变量名变量数据类型作用数组a[]int存储一段区间数组tr[]int表示树状数组 主要操作 函数名函数参数组要作用lowbit()int…

Linux-RedHat系统-安装 中间件 Tuxedo

安装步聚 一、中间件安装包&#xff1a; tuxedo121300_64_Linux_01_x86 Tuxedo下载地址&#xff1a; Oracle Tuxedo Downloads 二、新建用户&#xff1a; &#xff08;创建Oracle用户时&#xff0c;需要root权限操作&#xff09; 创建用户&#xff1a; # useradd oracle …

es6从url中获取想要的参数

第一种方法 很古老&#xff0c;通过 split 方法慢慢截取&#xff0c;可行是可行但是这个方法有一个弊端&#xff0c;因为 split 是分割成数组了&#xff0c;只能按照下标的位置获取值&#xff0c;所以就是参数位置一旦发生变化&#xff0c;那么获取到的值也就错位了 let user…

利用python将data:image/jpg; base64,格式数据转化下载为图片

在做爬虫爬取图片时&#xff0c;发现有的图片url是用“data:image/jpg;base64” 开头的&#xff0c;例如下图 部分开头样式如下&#xff1a; 1、data:image/jpg; base64, 2、data:image/png; base64, 3、data:image/webp;base64, 利用python进行代码进行图片下载&#xff0c;…

面向对象设计与分析40讲(22)罪恶的单例模式?

单例模式曾经被认为是一种重要的设计模式&#xff0c;但现在已经失去了很多开发者的青睐。虽然单例模式可能仍然适用于某些场景&#xff0c;但它的使用已经不再像过去那样普遍了。 单例模式是创建型设计模式的一种&#xff0c;它限制了一个类的实例化只能为一个实例&#xff0…

先进的Web3.0实战热门领域NFT项目几个总结分享

非同质化代币&#xff08;NFT&#xff09;的崛起为游戏开发者提供了全新的机会&#xff0c;将游戏内物品和资产转化为真正的可拥有和交易的数字资产。本文将介绍几个基于最先进的Web3.0技术实践的NFT游戏项目&#xff0c;并分享一些相关代码。 Axie Infinity&#xff08;亚龙无…

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

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

C++ extern “C“ 用法

extern “C” 由于c中需要支持函数重载&#xff0c;所以c和c中对同一个函数经过编译后生成的函数名是不相同的 extern “C” 的主要作用就是为了实现c代码能够调用其他 c 语言代码。 1(不常用) //告诉编译器 show() 函数按c语言的方式进行编译和链接 extern "C" voi…

MySQL数据库概念与实践

MySQL数据库概念与实践 1. 概念 MySQL是一种常用的关系型数据库管理系统&#xff0c;具有丰富的功能和广泛的应用。在本篇博客中&#xff0c;我们将介绍MySQL数据库的一些重要概念和相关知识。 存储引擎 存储引擎是MySQL数据库用于存储、更新和查询数据的技术实现方法。MyS…

Python安装第三方库出错

Python 程序包镜像的国内源如下&#xff1a; 清华大学: https://pypi.tuna.tsinghua.edu.cn/simple/豆瓣(douban): https://pypi.douban.com/simple/阿里云: https://mirrors.aliyun.com/pypi/simple/中国科技大学: https://pypi.mirrors.ustc.edu.cn/simple/ 使用方法&#xf…

件夹和文件比较软件VisualDiffer mac功能介绍

VisualDiffer mac是一款运行在MacOS上的文件夹和文件快速比较工具。VisualDiffer可以对不同文件夹中文件或文档做出比较或者比较两个文件的路径。还可以通过UNIS diff命令快速、标准和可靠的比较出各类不同的文件夹和文件结果&#xff0c;使用不同的颜色直观地显示。 VisualDif…

酷滴科技出席浦发银行第七届国际金融科技创新大赛

12月7日&#xff0c;浦发银行全球金融科技创新大赛在上海展开决赛。本届大会以“科技金融&#xff0c;激发创新力量”为主题&#xff0c;聚焦金融行业数字化转型过程中的痛点与难点&#xff0c;旨在探讨新时代下金融科技的新角色、新机遇以及新挑战。酷滴科技CEO张沈分享了酷滴…

12.11

1.q&#xff0c;w&#xff0c;e亮led1&#xff0c;2&#xff0c;3&#xff1b; a&#xff0c;s&#xff0c;d灭led1&#xff0c;2&#xff0c;3&#xff1b; main.c #include "uar1.h"#include "led.h"void delay(int ms){int i,j;for(i0;i<ms;i){for…

「CocoaPods」Podfile文件模板

前言&#xff1a;在iOS项目中&#xff0c;通常会使用到CocoaPods作为一个第三方库的依赖管理工具&#xff0c;可以简化对组件的依赖、更新的过程&#xff0c;本文将介绍在iOS项目中多Target企业级项目的Podfile文件编写格式 一、podfile介绍 先简单介绍一下podfile文件&#…

基于mdadm创建与管理软raid

环境 VMware workstation 17pro CentOS Linux release 7.9.2009 (Core) ——内存8G&#xff0c;16core ——硬盘系统盘100G ——四块20G硬盘 注意事项 1、在没有操作系统的情况下&#xff0c;可以在装系统时将磁盘做软raid&#xff0c;然后使用软raid作为系统盘 2、在重构时&a…

虚幻商城 道具汇总

文章目录 载具Vehicle Variety Pack(车辆品种包)Vehicle Variety Pack Volume 2(车辆品种包第 2 卷)家具Free Furniture Pack(免费家具包)Old West - VOL 1 - Interior Furniture(旧西部 - 第1卷 - 家具包)Old West VOL.3 - Travel Supplies and Goods(旧西部 - 第3卷…

容器及容器调度(云)

在云计算中&#xff0c;容器是一种轻量级、可执行的软件包&#xff0c;它包含应用程序及其全部依赖项&#xff0c;包括库、二进制文件、配置文件等。容器与虚拟机不同&#xff0c;因为它们不需要包含完整的操作系统&#xff1b;相反&#xff0c;所有容器都共享主机操作系统的内…