class Solution {
public:
vector<int> dailyTemperatures(vector<int>& temperatures) {
stack<int> st;
int n = temperatures.size();
vector<int> ans(n,0);
st.push(0);
for(int i=1;i<n;i++){
if(temperatures[i]<=temperatures[st.top()]){
st.push(i);
}
else{
while(!st.empty()&&temperatures[i]>temperatures[st.top()]){
ans[st.top()]=i-st.top();
st.pop();
}
st.push(i);
}
}
return ans;
}
};
单调栈的作用是高效地跟踪每一天的温度,帮助快速找到下一个更高温度的那一天,从而避免了不必要的重复计算。
具体作用如下:
保持栈内元素单调递减:
- 栈中的元素(即温度对应的索引)按照温度值单调递减排序。
- 当遍历到一个新的温度时,如果这个温度比栈顶元素所对应的温度高,那么栈顶元素就找到了第一个比它高的温度,可以弹出栈并计算相应的天数。
高效查找下一个更高温度:
- 由于栈是单调递减的,一旦找到一个更高温度,可以立即计算并更新栈顶索引对应的天数,无需再检查之前的所有元素。栈中的每个元素都只会被压入和弹出一次,因此保证了算法的时间复杂度为 O(n)。
减少不必要的比较:
- 如果不使用单调栈,可能需要对每一天都进行向后的遍历,来找到下一个更高温度,这样的算法时间复杂度为 O(n²)。
- 单调栈通过记录和更新索引的方式避免了重复计算,使得每个元素只被处理一次。
总结:
单调栈的主要作用在于保持栈内温度的单调递减,帮助快速找到并计算每一天遇到更高温度的等待天数,从而显著提高算法的效率。
代码逻辑总结:
初始化:
- 创建一个栈
st
来存储尚未找到更高温度的天的索引。- 获取温度列表的长度
n
,并初始化结果数组ans
,长度为n
,初始值全为 0。遍历温度列表:
- 对每个温度
temperatures[i]
,依次进行处理。- 如果栈不为空且当前温度
temperatures[i]
大于栈顶索引对应的温度temperatures[st.top()]
:
- 弹出栈顶索引,计算从该天到第
i
天所等待的天数,并将其存入结果数组ans
对应的位置。- 继续检查栈内的其他元素,直到栈为空或栈顶元素的温度不小于当前温度。
- 将当前天的索引
i
压入栈中,表示这一天的温度还没有找到比它更高的温度。返回结果:
- 当所有温度都处理完毕后,结果数组
ans
即为每一天需要等待的天数,最后返回该数组。总体思想:
通过栈的方式记录尚未确定答案的天数,并利用栈的后进先出特性,快速找到每一天之后遇到的第一个更高温度,实现时间复杂度为 O(n) 的算法。