当前位置: 首页 > news >正文

单调栈理解和实战

碎碎念:时隔多年,又回到了刷题状态,对单调栈又有了新的理解,这里记录一下作为备忘

所要解决的问题

通常单调栈用于解决:

给定数组 nums 求每个位置左右最近的大于/小于元素

典型问题:

  • RFG:右最近大于
  • RFS:右最近小于
  • LFG:左最近大于
  • LFS:左最近小于

引入例子

求当前位置的右最近大于元素(RFG)的索引,如果不存在返回数组大小

例如:

idx 0 1 2 3 4 nums = [3,1,2,4,3]

答案:

RFG = [3,2,3,5,5]

思路1:栈作为备选区

对称的版本,可以看看视频辅助理解:视频

核心思想:

当前元素去备选栈区中“找答案”

想象把栈横置作为备选答案区,盏口朝左,然后从右向左遍历

核心伪代码

注意栈中保存的是索引

# 从右往左遍历 n = len(nums) for i from n-1 -> 0: # 搜索答案,并去掉一些不可能成为答案的解,加速下轮搜索 while st非空 and nums[i] >= nums[st.top]: st.pop() RFG[i] = st.top if st非空 else n # 搜到了答案 st.push(i) # 加入备选区,开始新的一轮循环

解释

从右往左遍历求当前元素i的答案,迭代比较当前元素i和栈顶元素x(搜答案)

1.if 当前元素i >= 栈顶元素x:pop删除栈顶,并开始下一轮比较

这里在搜答案的过程中,通过pop操作删除备选区中无关的不可能成为后续迭代元素的答案的元素,从而避免重复搜索相同元素,进而加速后续元素的搜索答案过程

2.if 当前元素i < 栈顶元素x:则找到了当前元素i的RFG (右最近大于元素)为栈顶元素x

3.推论:由要点2结合算法的入栈过程,可以推断出,栈中相邻位置的元素,靠近栈底的元素是靠近栈顶元素的RFG

进阶思路2:栈作为待解区

核心思想:

入栈的元素作为待求解的元素,每次出栈时处理待求解栈顶元素,这种解法除了能够求RFG, 还能结合思路1求LFGE (左最近的大于等于)

想象将栈横置,盏口朝右

核心伪代码

# 添加哨兵元素,保证所有元素一定会pop出栈 nums.push(inf) n = len(nums) for i from 0 -> n-1: while st非空 and nums[st.top] < nums[i]: x = st.pop() RFG[x] = i # 求RFG # 同步获得的副产物 LFGE[x] = st.top if st非空 else -1 # 求LFGE st.push(i) # 去掉哨兵 nums.pop()

性质

  • 使栈顶出栈的元素i一定是栈顶元素x的RFG (简单来说这是因为i的右边的非RFG元素没有能力使得i出栈,而还会被算法push入栈成为新栈顶)
  • 结合思路1的推论3,栈顶元素x的往下一个元素一定是栈顶元素的LFGE!

延伸: 求严格的RFG和LFG

# 添加哨兵元素,保证所有元素一定会pop出栈 nums.push(inf) for i from 0 -> n-1: while st非空 and nums[st.top] < nums[i]: x = st.pop() RFG[x] = i # 求RFG # 去掉相等左元素 while st非空 and nums[st.top] == nums[x]: st.pop() # 求严格的LFG LFG[x] = st.top if st非空 else -1 st.push(i) # 去掉哨兵 nums.pop()

实战

Leetcode 84

https://leetcode-cn.com/problems/largest-rectangle-in-histogram/

先看题解的暴力解法,再看下面代码就好理解了

classSolution:# 单调栈:# 求每个柱子的:# 左最近 <= heights[x] 的位置# 右最近 < heights[x] 的位置## 从而确定包含柱x的高为 heights[x] 的矩形的最大宽度,最后得出潜在的矩形大小deflargestRectangleArea(self,heights:List[int])->int:# 添加哨兵,保证所有元素最终都会出栈结算heights.append(-float('inf'))n=len(heights)st=[]ans=0foriinrange(n):# 当前元素更小# 栈顶元素找到了右边界whilestandheights[st[-1]]>heights[i]:x=st.pop()# 右最近 < heights[x]rfs=i# 左最近 <= heights[x]lfse=st[-1]ifstelse-1# 确定最大宽度width=rfs-1-(lfse+1)+1# 更新答案ans=max(ans,width*heights[x])# 注意栈中存放的是索引st.append(i)returnans

更多利用单调栈性质相关的题目:

739 每日温度(中等) 暴力解法 + 单调栈
496 下一个更大元素 I(简单) 暴力解法、单调栈
901 股票价格跨度(中等) 「力扣」第 901 题:股票价格跨度(单调栈)

42 接雨水(困难) 暴力解法、优化、双指针、单调栈
581 最短无序连续子数组 单调栈、双指针

以下几题形似单调栈,但没有用到单调栈的性质,而是利用了贪心的思想
402 移掉K位数字
321 拼接最大数
316 去除重复字母(困难)

739 秒杀!

classSolution:defdailyTemperatures(self,temperatures:List[int])->List[int]:# 添加一个哨兵元素,保证所有元素都会出栈temperatures.append(float('inf'))n=len(temperatures)st=[]# 预置答案数组,可以随便初始化ans=[0]*(n-1)# 遍历当前位置foriinrange(n):whilestandtemperatures[st[-1]]<temperatures[i]:x=st.pop()# 右最近 > temperatures[x]rfg=i# 注意需要判断是否触及边界ans[x]=rfg-xifi<(n-1)else0st.append(i)# 删除哨兵temperatures.pop()returnans

581

未完待续…

http://www.jsqmd.com/news/1163601/

相关文章:

  • 远程操控自动机场起降,拼的不是胆量,而是系统
  • GRSL 2026 即插即用 | Transformer篇 | FEFFN:频域 - 空域联合建模,跨频交互,全局结构 + 局部细节全保留,根治传统 FFN 空间建模缺失
  • 2026 年现阶段,桥东值得关注的休息亭品牌哪家可靠,原来公园最舒服的不是长椅,而是这不起眼的角落。 - 企业官方推荐【认证】
  • elasticsearch学习笔记(三十五)——Elasticsearch 索引管理
  • 2026年7月沈阳​市公共卫生许可证检测集中空调通风系统检测水质检测空气质量甲醛检测怎么做?正规CMA机构办理指南 - 绿呼吸检测中心
  • 天津黄金回收指南:9种情况对号入座找对品牌不踩坑 - 资讯纵览
  • mysql-SQL语句执行过程
  • WebPShop:为Photoshop用户解锁专业级WebP图像处理能力
  • elasticsearch学习笔记(三十四)——Elasticsearch 基于scoll技术滚动搜索大量数据
  • 2026年7月衢州​市公共卫生许可证检测集中空调通风系统检测水质检测空气质量甲醛检测怎么做?正规CMA机构办理指南 - 绿呼吸检测中心
  • 2026年7月十堰​市公共卫生许可证检测集中空调通风系统检测水质检测空气质量甲醛检测怎么做?正规CMA机构办理指南 - 绿呼吸检测中心
  • AI 习惯追踪的反馈设计:鼓励不是堆砌赞美,而是记录可见进步
  • 基于MKV42F128VLH16与PAM8904的低功耗警报系统设计
  • 2026英语写作批改工具选型指南:行业痛点与AI技术路径深度解析
  • 2026年7月绍兴​市公共卫生许可证检测集中空调通风系统检测水质检测空气质量甲醛检测怎么做?正规CMA机构办理指南 - 绿呼吸检测中心
  • 2026年7月最新昆明欧米茄官方售后热线及客户服务网点地址 - 欧米茄服务中心
  • 2026年赤峰GEO系统贴牌服务商靠谱源头厂商综合实力推荐:本地合伙人如何选对OEM贴牌与技术加盟合作路径? - 小随科技
  • 2026年 软考备考指南及考前题型
  • 长沙黄金回收选哪家?这家全国连锁,不踩坑 - 小蝶回收测评
  • 2026年7月石家庄​市公共卫生许可证检测集中空调通风系统检测水质检测空气质量甲醛检测怎么做?正规CMA机构办理指南 - 绿呼吸检测中心
  • 四 、SCI常用性能表达词
  • elasticsearch学习笔记(三十三)——Elasticsearch Bouncing Results问题
  • STM32F405ZG与ADS131M02高精度ADC系统设计指南
  • 安科瑞面向购物中心 / 写字楼停车场 全场景充电桩智能运营整体解决方案
  • 2026最新卖家精灵优惠码最新汇总:单人版KJDSYY72、标准版及以上KJDSYY78 - 跨境电商卖家出海
  • QString完整详解
  • OpenAI 用 GPT-Live-1 全面升级 ChatGPT 语音模式,交互更自然还能实时翻译!
  • 2026年7月最新浪琴杭州东站万象汇维修保养服务电话 - 浪琴官方售后服务中心
  • 如何通过智能照明控制模块实现智慧城市照明管理?
  • Vitis IDE 导入 旧版SDK 工程步骤说明