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

一、题目概述

题目来源: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)

💬 一句话总结:

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

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

相关推荐
麦烤楽鸡翅2 小时前
挡住洪水 (牛客)
java·数据结构·c++·python·算法·bfs·牛客
MicroTech20252 小时前
微算法科技(NASDAQ MLGO)采用动态层次管理和位置聚类技术,修改pBFT算法以提高私有区块链网络运行效率
科技·算法·聚类
~~李木子~~2 小时前
五子棋项目Alpha-Beta剪枝与MCTS+神经网络实现人机对弈算法对比报告
神经网络·算法·剪枝
bigdata-rookie2 小时前
JVM 垃圾收集器介绍
java·jvm·算法
ʚ希希ɞ ྀ2 小时前
leeCode hot 100 !!!持续更新中
数据结构·算法·leetcode
lemontree19452 小时前
CRC8算法通用版本
算法
热爱生活的猴子2 小时前
算法322. 零钱兑换
算法
剪一朵云爱着2 小时前
力扣1539. 第 k 个缺失的正整数
算法·leetcode
摸鱼仙人~2 小时前
针对编程面试和算法题的基础书籍
算法·面试·职场和发展