739. 每日温度 LeetCode 热题 HOT 100

目录

过程解析

一、题目理解

给定一个数组,表示连续几天的气温。

要求输出一个同样长度的数组,其中第 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;
}
相关推荐
程序员莫小特3 小时前
老题新解|计算2的N次方
开发语言·数据结构·算法·青少年编程·信息学奥赛一本通
wearegogog1235 小时前
基于块匹配的MATLAB视频去抖动算法
算法·matlab·音视频
十重幻想5 小时前
PTA6-1 使用函数求最大公约数(C)
c语言·数据结构·算法
大千AI助手6 小时前
蛙跳积分法:分子动力学模拟中的高效数值积分技术
算法·积分·数值积分·蛙跳积分法·牛顿力学系统·verlet积分算法
zycoder.7 小时前
力扣面试经典150题day3第五题(lc69),第六题(lc189)
算法·leetcode·面试
西阳未落8 小时前
LeetCode——双指针
c++·算法
胖咕噜的稞达鸭9 小时前
C++中的父继子承:继承方式实现栈及同名隐藏和函数重载的本质区别, 派生类的4个默认成员函数
java·c语言·开发语言·数据结构·c++·redis·算法
笑口常开xpr9 小时前
【C++】模板 - - - 泛型编程的魔法模具,一键生成各类代码
开发语言·数据结构·c++·算法
IT小番茄10 小时前
Kubernetes云平台管理实战:自动加载到负载均衡(七)
算法