文章目录
一、题目简介
题目链接:
LeetCode:每日温度
题目描述:
给定一个整数数组 temperatures,表示每天的温度。请返回一个数组 answer,其中 answer[i] 表示第 ( i ) 天之后,需要等待多少天 才会出现更高的温度。如果之后没有更高的温度,请置为 0。
示例:
text
输入: temperatures = [73,74,75,71,69,72,76,73]
输出: [1,1,4,2,1,1,0,0]
二、问题分析
对于每个温度,我们希望知道下一个更高温度出现的间隔天数。这本质上是一个**"下一个更大元素"问题**的变体。
在这里,数组的元素是温度,而"更大元素"代表"更高温度的天数"。
三、解法思路总览
每日温度
暴力解法
=> 两层循环
=> 每天向后找更高温度
=> 时间复杂度 O(n²)
单调栈解法
=> 使用栈存储索引
=> 栈保持递减温度序
=> 遇到更高温度时出栈更新结果
=> 时间复杂度 O(n)
四、暴力解法
原理
对于每一天,往后依次查看未来的几天,直到找到一个温度更高的日期,并计算等待天数。
思路示意图
是
否
第 i 天温度
从 i+1 天起开始搜索
是否出现更高温度?
记录等待天数 j - i
返回 0
Java代码实现:
java
public int[] dailyTemperaturesBruteForce(int[] temperatures) {
int n = temperatures.length;
int[] res = new int[n];
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
if (temperatures[j] > temperatures[i]) {
res[i] = j - i;
break;
}
}
}
return res;
}
复杂度分析
| 指标 | 复杂度 |
|---|---|
| 时间复杂度 | ( O(n^2) ) |
| 空间复杂度 | ( O(1) ) |
缺点: 当数据量很大时性能极低,需要优化。
五、单调栈优化解法(推荐)
原理讲解
使用一个栈来存储尚未找到更高温度的"索引" 。
栈中的温度是自顶向下递减的 。
当我们遇到一个比栈顶温度高的温度时,就意味着栈顶对应的那一天终于"等到了更高温度"。
流程说明
假设温度数组为 [73,74,75,71,69,72,76,73]
我们逐日扫描:
- 第一天
73入栈。 - 第二天
74高于栈顶73→ 出栈并更新等待天数(1天)。 - 继续入栈新的温度。
- 重复上面的过程。
最终每个出栈时,都可以知道它要等待多少天。
时序图可视化
结果 栈 当前日 结果 栈 当前日 alt [当前温度更高] [当前温度不高] 比较温度 更新等待天数 出栈 入栈索引
Java代码实现:
java
import java.util.Stack;
public int[] dailyTemperatures(int[] temperatures) {
int n = temperatures.length;
int[] res = new int[n];
Stack<Integer> stack = new Stack<>();
for (int i = 0; i < n; i++) {
while (!stack.isEmpty() && temperatures[i] > temperatures[stack.peek()]) {
int prevIndex = stack.pop();
res[prevIndex] = i - prevIndex;
}
stack.push(i);
}
return res;
}
复杂度分析
| 指标 | 复杂度 |
|---|---|
| 时间复杂度 | ( O(n) ) --- 每个元素最多进出栈一次 |
| 空间复杂度 | ( O(n) ) --- 栈空间存储未匹配的索引 |
六、对比总结
| 解法 | 思路 | 时间复杂度 | 空间复杂度 | 优点 | 缺点 |
|---|---|---|---|---|---|
| 暴力解法 | 双重遍历 | O(n²) | O(1) | 简单易懂 | 性能较差 |
| 单调栈 | 栈存索引递减 | O(n) | O(n) | 高效、最优解 | 逻辑稍复杂 |