跳到正文
第 739 题中等

每日温度

Daily Temperatures

对每一天,求还要等几天才会出现更高温度;如果之后都不会升温,就填 0。

在力扣中练习

题目描述

给定一个整数数组 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]

 

提示:

  • 1 <= temperatures.length <= 105
  • 30 <= temperatures[i] <= 100

解题思路

主解法

单调栈 · 存下标

把还没等到答案的天攒在栈里,一升温就集中结算

为每一天向后扫描更暖天气,会重复检查很多相同区间。改成维护“还没等到答案的日子”,新温度到来时只结算比它低的栈顶。

自拟主例 [68,72,72,65,70,74,71],答案是 [1,4,3,1,1,0,0]。栈里保存下标,温度从栈底到栈顶不递增;两个 72 相等,都必须继续等待。

分步图解

第 1 天 72° 入栈,等待后续更高温度。

温度
0
1
2
3
4
5
6
68
72
72
65
70
74
71
i
answer
0: 11: 02: 03: 04: 05: 06: 0
还在等更暖的一天 · 温度 / 下标后进先出
72↓ 入栈
  1. 72第 1 天← top
栈底
1 / 3
相等温度继续等待,严格更高才结算。

74 到来时,70 和两个 72 会依次出栈。每弹出下标 j,等待天数就是当前下标 i 减 j,而不是温度差。

分步图解

第 4 天 70° 入栈,等待后续更高温度。

温度
0
1
2
3
4
5
6
68
72
72
65
70
74
71
i
answer
0: 11: 02: 03: 14: 05: 06: 0
还在等更暖的一天 · 温度 / 下标后进先出
70↓ 入栈
  1. 72第 1 天
  2. 72第 2 天
  3. 70第 4 天← top
栈底
1 / 5
一次升温可能连续结算多个更早的日子,每个下标只出栈一次。

每个下标只入栈一次、出栈一次。扫描结束后仍留在栈里的日子等不到更暖天气,答案保留初始的 0,不需要额外清栈填值。

时间 O(n)空间 O(n)

易错点

  • 把 while 写成 if:一次升温可能同时解决栈里好几天,比如 [75,71,69,72] 里的 72 要连弹两次。
  • 栈里存温度而不是下标,最后算不出「几天后」。
  • 比较写成 >=:温度相等不该算「更高」,会被提前弹出。
对照解法

暴力 · 往后找

对每一天向后扫,找到第一个更暖的为止

结果正确,但最坏 O(n²),大输入可能超时;仅用于理解单调栈消除了哪些重复扫描。

最直白的写法:对每个 i,从 i + 1 开始往后找第一个 temperatures[j] > temperatures[i],找到就填 j - i 并 break;扫到末尾都没找到,就保持 0。

它的正确性没有任何疑问,问题全在效率:数组严格递减时(比如 [100, 99, 98, ...]),每一天都要扫到末尾,总比较次数是 n²/2 级别。题目给到 10⁵,这个量级会超时。

不过它是理解单调栈的好起点:单调栈做的正是把这些「往后找」的扫描结果缓存下来——某一天如果已经被后来的暖天结算过,就再也不用为它重复扫描了。

写完暴力再回头看单调栈,会发现两者在枚举的对象上完全不同:暴力枚举「哪一天更暖」,单调栈枚举「哪一天还没答案」。

  1. 1answer 初始化为 0。
  2. 2外层 i 枚举每一天。
  3. 3内层 j 从 i + 1 往后找第一个更暖的天。
  4. 4找到就写 answer[i] = j - i 并 break。
时间 O(n²)空间 O(1)

易错点

  • 找到后忘记 break,后面的暖天会覆盖掉正确答案。
  • 内层循环写成 j <= n,越界访问 temperatures[n]。

代码与演示

主解法配有图解;对照解法用于比较思路、复杂度或实现方式。

演示输入temperatures = [68, 72, 72, 65, 70, 74, 71]

答案先填 0;栈保存等待中的下标,相等温度不会让栈顶出栈。

温度
0
1
2
3
4
5
6
68
72
72
65
70
74
71
answer
0: 01: 02: 03: 04: 05: 06: 0
还在等更暖的一天 · 温度 / 下标后进先出
从栈顶进入与离开
    空栈
    栈底
    1 / 14
    查看 C++ 代码

    延伸阅读

    • 单调栈模板就三行:栈非空且当前元素破坏单调性时,弹栈并结算答案;然后压栈。下一个更大元素(496/503)、接雨水(42)、柱状图中最大的矩形(84)都是它的变形。
    • 本题是「下一个更大元素」的距离版本:把 answer[j] = i - j 换成 answer[j] = temperatures[i],就变成了存值的版本。
    • 从右往左扫也能做,配合已经算好的 answer 往前跳,思路更接近记忆化;但单调栈的写法更统一,也更适合推广。