从零开始刷算法-单调栈-每日温度

一、题目概述

题目来源:LeetCode 739 - Daily Temperatures

题目要求:

给定一个整数数组 temperatures,表示每天的温度,返回一个数组 answer,其中 answer[i] 表示距离第 i 天之后,温度升高所需要的天数。如果之后没有更高的温度,则 answer[i] = 0

示例:

cpp 复制代码
输入: temperatures = [73,74,75,71,69,72,76,73]
输出: [1,1,4,2,1,1,0,0]

二、思路分析

这道题的核心在于:

对于每一天 i,要找到右边第一个比它温度高的那一天

如果我们暴力查找,每个 i 都向右扫描,复杂度是 O(n^2),显然不行。

于是可以考虑使用一个**单调栈(Monotonic Stack)**来优化。


三、单调栈思路讲解

1️⃣ 从后往前遍历的原因

我们从右往左遍历数组,因为:

  • 当前天的右边温度都已经处理完;

  • 栈中存放的下标对应的温度都是"右边的天",

  • 所以可以直接用栈顶判断"右边第一个更高温度"。

2️⃣ 栈中存什么?

栈中存放的是 下标 i ,而不是温度值。

因为要计算天数差(st.top() - i)。

3️⃣ 如何维护栈的单调性?

我们希望栈中的温度是递减的(栈顶最小)。

  • 当前温度 t 如果比栈顶温度高,说明栈顶那天不可能成为任何左边天的答案,直接 pop 掉;

  • 否则说明栈顶那天温度比当前天高,可以计算答案。

4️⃣ 状态更新逻辑

伪代码逻辑如下:

cpp 复制代码
for i 从右往左:
    当前温度 = t[i]
    while 栈不空 && 当前温度 >= 栈顶温度:
        弹栈(因为这些天对答案没贡献)
    if 栈不空:
        ans[i] = 栈顶下标 - i
    压入当前下标 i

四、完整代码实现

cpp 复制代码
class Solution {
public:
    vector<int> dailyTemperatures(vector<int>& temperatures) {
        int n = temperatures.size();
        vector<int> ans(n);
        stack<int> st;  // 单调递减栈,存放下标

        for (int i = n - 1; i >= 0; i--) {
            int t = temperatures[i];
            while (!st.empty() && t >= temperatures[st.top()]) {
                st.pop();
            }
            if (!st.empty()) {
                ans[i] = st.top() - i;
            }
            st.push(i);
        }

        return ans;
    }
};

五、运行流程示例

以输入 [73,74,75,71,69,72,76,73] 为例:

i 温度 栈中下标(从栈底到栈顶) 栈中对应温度 ans[i] 说明
7 73 [7] [73] 0 栈空,压入
6 76 [] [] 0 76>73,弹出后压入
5 72 [6,5] [76,72] 1 栈顶温度76更高
4 69 [6,5,4] [76,72,69] 1 栈顶温度72更高
3 71 [6,5,3] [76,72,71] 2 下一个高温是72
2 75 [6,2] [76,75] 4 下一个高温是76
1 74 [6,2,1] [76,75,74] 1 下一个高温是75
0 73 [6,2,1,0] [76,75,74,73] 1 下一个高温是74

六、复杂度分析

  • 时间复杂度: O(n),每个元素最多被压栈和弹栈一次。

  • 空间复杂度: O(n),栈最多存储 n 个下标。


七、总结

特点 说明
遍历方向 从右往左更自然
栈结构 单调递减栈
栈中存储 温度下标
逻辑核心 弹出无用天,栈顶即为最近更高温度
时间复杂度 O(n)

💬 一句话总结:

单调栈的关键不是"栈"本身,而是"单调性"带来的剪枝。

我们用栈保证每次处理时,能立刻找到"右边第一个更大元素"。

相关推荐
代码游侠10 小时前
应用——管道与文件描述符
linux·服务器·c语言·学习·算法
一招定胜负10 小时前
决策树开篇
算法·决策树·机器学习
GoWjw10 小时前
C语言高级特性
c语言·开发语言·算法
carver w10 小时前
说人话版 K-means 解析
算法·机器学习·kmeans
小O的算法实验室10 小时前
2026年SEVC SCI2区,基于差分向量内学习策略的自适应指数交叉差分进化算法,深度解析+性能实测
算法·论文复现·智能算法·智能算法改进
gloomyfish11 小时前
【最新技术】多模态零样本工业缺陷检测概述
人工智能·算法·计算机视觉
渡过晚枫11 小时前
[蓝桥杯/java/算法]攻击次数
java·算法·蓝桥杯
风筝在晴天搁浅11 小时前
hot100 3.无重复字符的最长子串
数据结构·算法·leetcode
liuyao_xianhui11 小时前
寻找旋转排序数组中的最小值_优选算法(二分算法)
算法
努力学算法的蒟蒻11 小时前
day37(12.18)——leetcode面试经典150
算法·leetcode·面试