单调栈思想及其应用

单调栈,顾名思义就是栈内元素单调排列的栈,分为单调递增栈和单调递减栈。

单调递增栈:从栈底到栈顶,元素从大到小排列;即元素出栈序列为单调递增的。

单调递减栈:从栈底到栈顶,元素从小到大排列;即元素出栈序列为单调递减的。

常见作用:

在数组(数字序列)中为任意一个元素,找 左/右 边第一个比自己 大/小 的元素。

算法步骤:

例如:序列 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;
}
复制代码

 


 

我也总结了向左/右寻找下一个更大/小元素的做法:

左边第一个更小:单调递减栈,顺序遍历(同上例题)

左边第一个更大:单调递增栈,顺序遍历

右边第一个更小:单调递减栈,逆序遍历

右边第一个更大:单调递增栈,逆序遍历

 


 力扣经典单调栈题目:

739. 每日温度 - 力扣(LeetCode) 

503. 下一个更大元素 II - 力扣(LeetCode)

 

posted @   blazerrr  阅读(135)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示