单调栈(Monotonic Stack)是一种特殊的栈结构,它在算法问题解决中扮演着重要角色,尤其擅长处理"下一个更大/更小元素"这类问题。本文将系统性地介绍单调栈的核心原理、应用场景以及实际代码实现,帮助你彻底掌握这一重要数据结构。
一、什么是单调栈
(1)定义:
单调栈是一种保持栈内元素单调性(单调递增或单调递减)的特殊栈结构。它通过巧妙地维护元素的单调性,可以在O(n)时间复杂度内解决许多看似复杂的问题。
(2)基本特性
单调性:栈内元素始终保持单调递增或递减
操作方式:新元素入栈前,会先移除破坏单调性的栈顶元素
时间复杂度:每个元素最多入栈和出栈一次
二、单调栈的工作原理
(1)单调递增栈
维护栈内元素从栈底到栈顶递增的顺序。适合解决"下一个更小元素"类问题。
可用模板
for 元素 in 序列:
while 栈非空且当前元素 < 栈顶元素:
弹出栈顶元素
处理弹出的元素(如记录结果)
当前元素入栈
(2)单调递减栈
维护栈内元素从栈底到栈顶递减的顺序。适合解决"下一个更大元素"类问题。递减符号则改为>
这么看来可能会有些不好理解通俗点来讲就是要保证栈单调递增,当遍历一个数时当前这个数小于栈顶元素这样就破坏了单调递增栈,我们想让这个数入栈就得把目前大于当前这个数的栈顶元素出栈,直到当前数大于当前的栈顶元素再进栈,单调递减栈则相反。原理已经说完接下来就通过实例来深入学习。
三、单调栈的实战详解
1.力扣739.每日温度(点击直达)
给定一个整数数组 temperatures
,表示每天的温度,返回一个数组 answer
,其中 answer[i]
是指对于第 i
天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0
来代替。
示例 1:
输入: temperatures = [73,74,75,71,69,72,76,73]
输出: [1,1,4,2,1,1,0,0]
示例 2:
输入: temperatures = [30,40,50,60]
输出: [1,1,1,0]
示例 3:
输入: temperatures = [30,60,90]
输出: [1,1,0]
从这题分析来看下个更高温度出现在几天后,是单调递增但仔细分析从左往右遍历有些复杂,我就反过来从右往左遍历,当然题目单调递减也不包含等于,这么一分析直接套用模板
class Solution {
public:
vector<int> dailyTemperatures(vector<int>& temperatures) {
stack<int> st;
int n=temperatures.size();
vector<int> ans(n,0);
for(int i=n-1;i>=0;i--){
int t=temperatures[i];
while(!st.empty()&&t>=temperatures[st.top()]){
st.pop();
}
if(!st.empty()){
ans[i]=st.top()-i;
}
st.push(i);
}
return ans;
}
};
相关题目推荐
1475.商品折扣后的价格
496.下一个更大元素
后续更多题目可自行寻找,各位看官觉得有用就点个免费的赞吧!!!