LeetCode - 739.每日温度问题单调栈解法

LeetCode - 739.每日温度问题单调栈解法

目录

TOC

问题描述

给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 表示在第 i 天之后,需要等待多少天才能遇到更高的温度。若未来没有更高温度,则 answer[i] = 0 。

示例 :

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

第 0 天温度为 73,第 1 天温度为 74,因此只需等待 1 天;第 6 天温度为 76,后续没有更高温度,结果为 0。

方法思路:单调栈
核心思想

利用 单调递减栈 存储尚未找到更高温度的日期索引。栈中元素对应的温度从栈底到栈顶严格递减。遍历温度数组时,若当前温度高于栈顶温度,则栈顶元素找到了下一个更高温度的日期,计算天数差并更新结果,确保栈的单调性。

为什么用单调栈?
  • 暴力法的不足 :对每一天向后遍历找更高温度,时间复杂度为 O(n²),无法处理大规模数据。

  • 单调栈的优势 :每个元素最多入栈和出栈一次,时间复杂度优化至 O(n)。

算法步骤
  1. 初始化 :结果数组 ans 初始化为全 0,栈 stack 存储索引。

  2. 遍历温度数组 :对于第 i 天的温度 T[i] :

  • 循环检查栈顶 :若 T[i] > T[栈顶索引] ,说明栈顶元素的下一个更高温度是第 i 天:

  • 弹出栈顶索引 prevIndex ,计算 ans[prevIndex] = i - prevIndex 。

  • 维护单调性 :将 i 压入栈,保持栈内温度递减。

  1. 返回结果 :遍历结束后, ans 数组即为所求。
代码实现与逐行解析
cobol 复制代码
var dailyTemperatures = function (temperatures) {
    const n = temperatures.length;
    const ans = new Array(n).fill(0); // 初始化结果数组为全0
    const stack = []; // 单调栈存储索引,栈底到栈顶温度递减
    
    for (let i = 0; i < n; i++) {
        // 当前温度 > 栈顶温度时,循环处理栈顶元素
        while (stack.length && temperatures[i] > temperatures[stack[stack.length - 1]]) {
            const prevIndex = stack.pop(); // 弹出栈顶索引
            ans[prevIndex] = i - prevIndex; // 计算天数差
        }
        stack.push(i); // 当前索引入栈,保持栈的单调性
    }
    return ans;
};

初始化结果数组 : ans 初始化为全 0,默认未来没有更高温度时结果为 0。

遍历温度数组 :对每一天的温度进行处理。

循环处理栈顶元素 :当栈不为空且当前温度高于栈顶温度时:

弹出栈顶索引 :获取需要更新结果的日期 prevIndex 。

计算等待天数 :结果为当前日期 i 与 prevIndex 的差值。

压入当前索引 :确保栈内温度保持递减。

示例解析

以 temperatures = [73,74,75,71,69,72,76,73] 为例,逐步分析栈和结果的变化:

当前索引 i 当前温度 T[i] 栈状态 (索引) 操作 结果数组 ans
0 73 \[\] 0入栈 0,0,0,0,0,0,0,0
1 74 0 73 < 74 → 计算ans0=1,0出栈,1入栈 1,0,0,0,0,0,0,0
2 75 1 74 < 75 → 计算ans1=1,1出栈,2入栈 1,1,0,0,0,0,0,0
3 71 2 75 > 71 → 3入栈 无变化
4 69 2,3 71 > 69 → 4入栈 无变化
5 72 2,3,4 69 < 72 → 计算ans4=1,4出栈;71 <72 → 计算ans3=2,3出栈;75 >72 → 5入栈 1,1,0,2,1,0,0,0
6 76 2,5 72 <76 → 计算ans5=1,5出栈;75 <76 → 计算ans2=4,2出栈;栈空 → 6入栈 1,1,4,2,1,1,0,0
7 73 6 76 >73 → 7入栈 无变化

最终结果为 [1,1,4,2,1,1,0,0] 。


复杂度分析
  • 时间复杂度 :O(n),每个元素最多入栈和出栈一次,总操作次数为 2n。

  • 空间复杂度 :O(n),栈的最大空间为 n(当温度严格递减时)。


总结

单调栈通过维护温度递减的索引序列,将问题的复杂度优化至线性时间。算法核心在于利用栈的单调性快速找到下一个更高温度的日期,避免了重复遍历。这种方法在处理"寻找下一个更大元素"类问题时非常高效。

相关推荐
wshzd几秒前
LLM之Agent(104)|DeepSeek-Harness(十三)ReactLoopAgent 总览:kick → turn → step
开发语言·前端·javascript
茉莉玫瑰花茶8 分钟前
OpenGL [ 基础概念 ]
java·前端·数据库
随性而行36015 分钟前
企业微信二次开发如何接入大模型工具?API接口实现智能任务调用的技术思路
java·前端·人工智能·python·微信·机器人·企业微信
IMPYLH24 分钟前
HTML 的 <td> 元素
前端·html
gnip35 分钟前
Flutter GetX 三件套开发规范(Skill)
前端·flutter
张小姐的猫1 小时前
【AI大模型接入SDK】 —— 前端页面 & 项目总结与拓展
前端·数据结构·数据库·c++·人工智能·chatgpt
web打印社区1 小时前
远程打印:WebSocket 与 HTTP 轮询怎么选
前端·vue.js·websocket·网络协议·http·electron·pdf
吴声子夜歌1 小时前
HTML——庞杂的表单控件元素(一)
前端·html
天天喝旺仔1 小时前
浏览器渲染原理:从解析 HTML/CSS、构建渲染树到重排重绘与首屏优化
前端·javascript·css·性能优化·html
明月_清风1 小时前
前端已死?别急,这可能只是所有行业的开始
前端·ai编程