单调栈思想及其应用
单调栈,顾名思义就是栈内元素单调排列的栈,分为单调递增栈和单调递减栈。
单调递增栈:从栈底到栈顶,元素从大到小排列;即元素出栈序列为单调递增的。
单调递减栈:从栈底到栈顶,元素从小到大排列;即元素出栈序列为单调递减的。
常见作用:
在数组(数字序列)中为任意一个元素,找 左/右 边第一个比自己 大/小 的元素。
算法步骤:
例如:序列 3 4 2 7 5 ,输出每一个元素左边第一个比它小的数字(没有则输出-1)。
寻找前一个更小的元素,使用单调递减栈。
一开始,输出-1,3 入栈,;栈状态:3
然后 4 和栈顶 3 对比,发现 4 > 3 ,输出 3,4 入栈;栈状态:3 4
然后 2 和栈顶 4 对比,发现 2 < 4 ,想找到比 2 小的元素,所以需要不断弹栈,弹出栈顶元素;所以 4 弹栈,3 弹栈,栈为空,输出-1,2 入栈;栈状态:2
然后 7 和栈顶 2 对比,发现 7 > 2 ,输出 2,7 入栈;栈状态:2 7
最后 5 和栈顶 7 对比,发现 5 < 7,7 弹栈,找到 2 比 5 小,输出 2 ,5 入栈;栈状态:2 5
所以答案为 -1,3,-1,2,2
题目:
实现代码:
#include<iostream> using namespace std; int main(){//单调栈思想,边读入边做单调栈,栈顶元素表示该栈最大元素,若当前读入元素小于等于栈顶元素 //栈顶元素没用了,因为相对于后面的读入,当前元素是更好的选择,因此栈顶弹栈,直到在栈内找到小于当前元素的,输出 //或者找不到输出-1,最后把当前元素加入栈顶 int n; int *stk=new int[n]; int num; int st=0;//本st表示栈内元素个数 cin>>n; for(int i=0;i<n;i++){ cin>>num; while(st&&stk[st-1]>=num)st--; if(st)cout<<stk[st-1]<<" "; else cout<<"-1 "; stk[st++]=num; } return 0; }
我也总结了向左/右寻找下一个更大/小元素的做法:
左边第一个更小:单调递减栈,顺序遍历(同上例题)
左边第一个更大:单调递增栈,顺序遍历
右边第一个更小:单调递减栈,逆序遍历
右边第一个更大:单调递增栈,逆序遍历
力扣经典单调栈题目:
503. 下一个更大元素 II - 力扣(LeetCode)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具