每日温度 (LeetCode 739)
给定一个整数数组 temperatures 表示每日的温度,返回一个数组 answer,其中 answer[i] 表示对于第 i 天,需要等待多少天才能等到更高的温度。如果之后都没有更高的温度,则 answer[i] = 0。
算法思路:单调递减栈
维护一个存储索引的单调递减栈(栈中元素对应的温度依次递减):
- 遍历温度数组,对于每个位置
i - 若栈不为空且
temperatures[i] > temperatures[st.top()],说明找到了栈顶日期之后的第一个更高温度 - 弹出栈顶,计算等待天数:
i - st.top() - 重复直至栈空或温度不满足条件
- 将当前索引
i入栈
核心思想
单调栈用于解决”下一个更大/更小元素”问题:
- 递减栈:找下一个更大元素
- 递增栈:找下一个更小元素
C++ 代码实现
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
vector<int> dailyTemperatures(vector<int>& temperatures) {
int n = temperatures.size();
vector<int> answer(n, 0);
stack<int> st; // 存储索引,栈中温度单调递减
for (int i = 0; i < n; ++i) {
// 若当前温度高于栈顶日期的温度,找到栈顶日期的答案
while (!st.empty() && temperatures[i] > temperatures[st.top()]) {
int prevDay = st.top();
st.pop();
answer[prevDay] = i - prevDay;
}
st.push(i);
}
return answer;
}
};执行流程示例
temperatures = [73, 74, 75, 71, 69, 72, 76, 73]
i=0: st=[0], answer=[0,0,0,0,0,0,0,0]
i=1: 74>73, pop 0, answer[0]=1; st=[1]
i=2: 75>74, pop 1, answer[1]=1; st=[2]
i=3: 71<75, push; st=[2,3]
i=4: 69<71, push; st=[2,3,4]
i=5: 72>69(pop),72>71(pop),72<75(push); st=[2,5], answer[4]=1,answer[3]=1
i=6: 76>72(pop),76>75(pop); st=[6], answer[5]=1,answer[2]=4
i=7: 73<76, push; st=[6,7]
最终: answer = [1,1,4,2,1,1,0,0]
复杂度分析
- 时间复杂度:,每个元素最多入栈和出栈各一次
- 空间复杂度:,最坏情况下栈存储所有索引