【Leetcode hot 100】739.每日温度
问题链接
739.每日温度
问题描述
给定一个整数数组 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 <= 10^530 <= temperatures[i] <= 100
问题解答
解法1:暴力解法(基础思路)
核心逻辑
对每个温度 temperatures[i],直接遍历其后面的所有温度,找到第一个比它大的温度,计算间隔天数;若遍历结束未找到,则间隔为 0。
代码实现
class Solution {public int[] dailyTemperatures(int[] temperatures) {int n = temperatures.length;int[] answer = new int[n]; // 结果数组,默认初始化为0// 遍历每个温度(最后一个温度无需遍历,结果必为0)for (int i = 0; i < n - 1; i++) {// 遍历i之后的温度,找第一个比temperatures[i]大的for (int j = i + 1; j < n; j++) {if (temperatures[j] > temperatures[i]) {answer[i] = j - i; // 计算间隔天数break; // 找到后立即退出内层循环,避免多余计算}}// 若未找到,answer[i]保持初始值0}return answer;}
}
复杂度分析
- 时间复杂度:
O(n^2)。最坏情况下(温度严格递减,如[5,4,3,2,1]),每个元素需遍历后面所有元素,总操作数为n(n-1)/2。 - 空间复杂度:
O(1)。仅用常数额外空间(结果数组answer为题目要求输出,不计入额外空间)。
局限性
当 n = 10^5 时,O(n^2) 会触发超时(操作数达 10^10,远超计算机每秒 10^8 操作上限),因此仅适用于理解基础逻辑,实际需用更高效解法。
解法2:单调栈解法(最优效率)
核心思路
利用单调递减栈存储温度的索引(而非温度值),通过栈的“单调性”快速定位“下一个更高温度”:
- 栈中始终保持“索引对应的温度严格递减”的顺序(栈顶是当前最小温度的索引)。
- 遍历每个温度
temperatures[i]:- 若当前温度 > 栈顶索引对应的温度,说明栈顶索引的“下一个更高温度”就是当前
i,计算间隔i - 栈顶索引并更新结果,然后弹出栈顶(继续检查新栈顶)。 - 若当前温度 ≤ 栈顶索引对应的温度,将当前索引
i压入栈(维持递减顺序)。
- 若当前温度 > 栈顶索引对应的温度,说明栈顶索引的“下一个更高温度”就是当前
- 遍历结束后,栈中剩余索引的“下一个更高温度”不存在,结果保持
0。
代码实现
class Solution {public int[] dailyTemperatures(int[] temperatures) {int n = temperatures.length;int[] answer = new int[n];Deque<Integer> stack = new LinkedList<>(); // 单调递减栈,存储温度的索引for (int i = 0; i < n; i++) {// 核心逻辑:当前温度 > 栈顶索引的温度,说明找到栈顶的“下一个更高温度”while (!stack.isEmpty() && temperatures[i] > temperatures[stack.peek()]) {int prevIndex = stack.pop(); // 弹出栈顶(已找到结果)answer[prevIndex] = i - prevIndex; // 计算间隔天数}// 维持栈的递减顺序,压入当前索引stack.push(i);}// 栈中剩余索引的结果已默认是0,无需额外处理return answer;}
}
复杂度分析
- 时间复杂度:
O(n)。每个索引仅会被压入栈一次、弹出栈一次,总操作数为2n,属于线性时间。 - 空间复杂度:
O(n)。最坏情况下(温度严格递减,如[5,4,3,2,1]),栈会存储所有n个索引。
关键优势
- 彻底解决超时问题,适配
n = 10^5的最大约束。 - 逻辑清晰:通过栈的单调性避免重复遍历,每一步操作都有明确目的。
两种解法对比
| 解法 | 时间复杂度 | 空间复杂度 | 适用场景 |
|---|---|---|---|
| 暴力解法 | O(n^2) | O(1) | 理解基础逻辑、小规模数据 |
| 单调栈解法 | O(n) | O(n) | 实际工程、大规模数据(推荐) |
