cpp
class Solution {
public:
vector<int> dailyTemperatures(vector<int>& temperatures) {
int n = temperatures.size();
vector<int> ans(n); // 结果集,记录每一天还要等几天才有更高温度
stack<int> s; // 单调栈,存放还没找到更高温度的下标
for (int i = 0; i < n; i++) {
// 当前温度 > 栈顶下标对应的温度
// 说明栈顶那一天找到了之后第一个更高温度
while (s.empty() == false &&
temperatures[i] > temperatures[s.top()]) {
int pre = s.top(); // 取出之前那一天的下标
s.pop(); // 已经找到答案,移出栈
ans[pre] = i - pre; // 计算相隔天数
}
// 当前这一天入栈,等待后面出现更高温度
s.push(i);
}
return ans;
}
};
总结
这道题使用的是单调递减栈 ,栈中存的是下标,不是温度。
核心逻辑就是:
遍历当前温度 temperatures[i]
如果 当前温度 > 栈顶对应温度
↓
说明栈顶那一天找到更高温度
↓
ans[栈顶] = 当前下标 - 栈顶下标
↓
pop() 出栈
↓
继续比较新的栈顶
如果当前温度不能解决栈顶
↓
停止 pop
最后
↓
当前下标 i 入栈
等待以后更高的温度
最重要的代码模板可以记住:
while (!s.empty() && 当前元素 > 栈顶元素) {
// 处理栈顶
s.pop();
}
s.push(当前元素);
这道题中因为需要计算距离多少天:
ans[pre] = i - pre;
所以栈里必须保存下标 i。
时间复杂度:O(n),因为每个下标最多入栈一次、出栈一次。
空间复杂度:O(n),最坏情况下温度一直下降,所有下标都会留在栈中。