目录
过程解析
一、题目理解
给定一个数组,表示连续几天的气温。
要求输出一个同样长度的数组,其中第 i
个元素表示:
从第 i
天起,至少需要等待多少天 才会出现比第 i
天更高的温度 。
如果之后再也没有更高温度,则输出 0
。
例如:
输入 [73, 74, 75, 71, 69, 72, 76, 73]
输出 [1, 1, 4, 2, 1, 1, 0, 0]
解释:
- 第 1 天(73)→ 下一天 74 更高 → 等 1 天;
- 第 2 天(74)→ 下一天 75 更高 → 等 1 天;
- 第 3 天(75)→ 要等到 76 (第 7 天)→ 等 4 天;
- ...依此类推。
二、核心思路
这题的关键在于:为每一天找到"右边第一个比它大的温度" 。
直接两层循环比对虽然能做,但时间复杂度是 O(n²),在数据量大时会超时。
于是可以使用一种经典的数据结构------单调栈(Monotonic Stack)。
三、单调栈思想
1. 栈的作用
我们维护一个栈,里面存放还没找到更高温度 的"天数下标"。
栈从底到顶保证:对应的温度是递减的。
2. 遍历数组的过程
当我们从左到右依次查看每一天时:
-
如果当天温度 ≤ 栈顶下标对应的温度:
表示当前还没有更高温度,把当天下标压入栈,等待后续更高的温度。
-
如果当天温度 > 栈顶下标对应温度:
说明当前这一天就是栈顶那天的"更高温度"。
我们可以计算两天的间隔天数:
当前天数索引 - 栈顶天数索引。
然后弹出栈顶,因为它已经找到了答案。
接着继续判断新的栈顶(可能连续几个更低温度都会被解决)。
这样,每个元素最多进栈一次、出栈一次,所以整个过程是 O(n) 的。
四、示例讲解
以输入数组:
73, 74, 75, 71, 69, 72, 76, 73
步骤演示
步骤 | 当前天数 | 当前温度 | 栈中下标(对应温度) | 操作 | 结果变化 |
---|---|---|---|---|---|
1 | 0 | 73 | [ ] | 栈为空,入栈 0 | 栈 → [0] |
2 | 1 | 74 | [0(73)] | 74 > 73,弹 0,ans[0]=1 | 栈 → [1] |
3 | 2 | 75 | [1(74)] | 75 > 74,弹 1,ans[1]=1 | 栈 → [2] |
4 | 3 | 71 | [2(75)] | 71 ≤ 75,入栈 3 | 栈 → [2, 3] |
5 | 4 | 69 | [2(75), 3(71)] | 69 ≤ 71,入栈 4 | 栈 → [2, 3, 4] |
6 | 5 | 72 | [2(75), 3(71), 4(69)] | 72 > 69 → 弹 4 (ans[4]=1),72 > 71 → 弹 3 (ans[3]=2),栈顶 75 > 72 → 停止,入 5 | 栈 → [2, 5] |
7 | 6 | 76 | [2(75), 5(72)] | 76 > 72 → 弹 5 (ans[5]=1),76 > 75 → 弹 2 (ans[2]=4),栈空,入 6 | 栈 → [6] |
8 | 7 | 73 | [6(76)] | 73 ≤ 76,入 7 | 栈 → [6, 7] |
遍历结束后,栈中 6 (76) 和 7 (73) 没有找到更高温度,保持默认值 0。
最终答案: [1, 1, 4, 2, 1, 1, 0, 0]。
五、算法总结
-
算法类型:单调栈(递减栈)
-
时间复杂度:O(n)(每个元素最多进栈一次、出栈一次)
-
空间复杂度:O(n)(栈与答案数组所占空间)
-
适用场景:
- 寻找"右侧第一个比当前值更大/更小"的元素
- 常用于温度、股票、地形等类似问题
代码
C++
cpp
class Solution {
public:
vector<int> dailyTemperatures(vector<int>& temperatures) {
int count = temperatures.size();
vector<int> ans(count,0);
stack<int> st;
for(int i = 0;i<count;i++){
while(!st.empty()&&temperatures[i]>temperatures[st.top()]){
auto index = st.top();
st.pop();
ans[index] = i - index;
}
st.push(i);
}
return ans;
}
};
C语言
c
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* dailyTemperatures(int* temperatures, int temperaturesSize, int* returnSize) {
int* ans = (int*)calloc(temperaturesSize, sizeof(int));
int* stack = (int*)malloc(sizeof(int) * temperaturesSize);
int top = -1;
for (int i = 0; i < temperaturesSize; i++) {
while (top >= 0 && temperatures[i] > temperatures[stack[top]]) {
int index = stack[top--];
ans[index] = i - index;
}
stack[++top] = i;
}
*returnSize = temperaturesSize;
free(stack);
return ans;
}