当前位置: 首页 > news >正文

单调栈入门到精通:每日温度 柱状图中最大的矩形

目录

一、入门题:739. 每日温度(中等)

题目描述

核心思路:单调栈的本质

代码实现(Java)

复杂度分析

二、进阶题:84. 柱状图中最大的矩形(困难)

题目描述

核心思路:用单调栈找边界

解题步骤

代码实现(Java)

复杂度分析

三、两道题的核心模板总结

通用解题步骤


今天我们用两道经典的「单调栈」题目,带你从入门到精通这个算法模板。

  • 入门题:LeetCode 739. 每日温度
  • 进阶题:LeetCode 84. 柱状图中最大的矩形

这两道题是单调栈的 “黄金模板”,搞懂它们,面试中 90% 的单调栈题目都能迎刃而解。


一、入门题:739. 每日温度(中等)

题目描述

给定一个整数数组temperatures,表示每天的温度,返回一个数组answer,其中answer[i]是指对于第i天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用0来代替。

示例:输入:temperatures = [73,74,75,71,69,72,76,73]输出:[1,1,4,2,1,1,0,0]

核心思路:单调栈的本质

这道题的本质,是找「下一个比当前大的数」

暴力解法是双重循环,时间复杂度 O (n²),但我们可以用单调栈把它优化到 O (n)。

单调栈的核心逻辑:

  1. 我们维护一个栈,栈中元素是温度的索引,并且它们对应的温度是单调递减的。
  2. 遍历每一天的温度:
    • 如果当前温度 > 栈顶索引对应的温度:说明找到了栈顶元素的 “下一个更高温度”。
    • 弹出栈顶元素,计算两者的索引差,就是答案。
    • 重复这个过程,直到栈顶元素对应的温度 >= 当前温度,再把当前索引入栈。

代码实现(Java)

java

运行

public int[] dailyTemperatures(int[] temperatures) { int n = temperatures.length; int[] answer = new int[n]; // 栈中存储索引,保证索引对应的温度单调递减 Deque<Integer> stack = new LinkedList<>(); for (int i = 0; i < n; i++) { while (!stack.isEmpty() && temperatures[i] > temperatures[stack.peek()]) { int prevIndex = stack.pop(); answer[prevIndex] = i - prevIndex; } stack.push(i); } return answer; }

复杂度分析

  • 时间复杂度:O (n),每个元素最多入栈和出栈一次。
  • 空间复杂度:O (n),最坏情况下所有元素都入栈。

二、进阶题:84. 柱状图中最大的矩形(困难)

题目描述

给定n个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1。求在该柱状图中,能够勾勒出来的矩形的最大面积。

核心思路:用单调栈找边界

这道题的关键是,以每一根柱子的高度为矩形的高,找到它能扩展的最大宽度

  • 对于高度为h[i]的柱子,我们需要找到:
    1. 左边第一个比它矮的柱子的索引left
    2. 右边第一个比它矮的柱子的索引right
  • 那么以h[i]为高的矩形的宽度就是right - left - 1,面积就是h[i] * (right - left - 1)

单调栈,正是解决 “找左右边界” 的神器。

解题步骤

  1. 哨兵优化:在数组首尾各加一个高度为 0 的哨兵,避免栈为空或无法出栈的边界情况。
  2. 维护单调递增栈:栈中存储柱子的索引,保证它们对应的高度是单调递增的。
  3. 遍历计算面积
    • 当遇到一个比栈顶元素矮的柱子时,栈顶元素找到了它的 “右边界”。
    • 弹出栈顶元素cur,此时的栈顶就是它的 “左边界”。
    • 计算以cur为高的矩形面积,并更新最大值。

代码实现(Java)

java

运行

public int largestRectangleArea(int[] heights) { // 哨兵优化,首尾加 0 int n = heights.length; int[] newHeights = new int[n + 2]; System.arraycopy(heights, 0, newHeights, 1, n); Deque<Integer> stack = new LinkedList<>(); int maxArea = 0; for (int i = 0; i < newHeights.length; i++) { // 维护单调递增栈 while (!stack.isEmpty() && newHeights[i] < newHeights[stack.peek()]) { int curIndex = stack.pop(); int height = newHeights[curIndex]; int width = i - stack.peek() - 1; maxArea = Math.max(maxArea, height * width); } stack.push(i); } return maxArea; }

复杂度分析

  • 时间复杂度:O (n),每个元素最多入栈和出栈一次。
  • 空间复杂度:O (n),最坏情况下所有元素都入栈。

三、两道题的核心模板总结

这两道题,其实是单调栈的两种典型应用场景:

表格

题目栈的单调性核心作用
每日温度单调递减栈下一个更大元素
柱状图最大矩形单调递增栈左右第一个更小元素

通用解题步骤

  1. 明确问题:你要找的是 “下一个更大 / 更小”,还是 “左右边界”?
  2. 选择单调性
    • 找下一个更大元素:用单调递减栈
    • 找下一个更小元素:用单调递增栈
  3. 处理边界:使用哨兵(在数组首尾加 0)是简化代码的常用技巧。。
http://www.jsqmd.com/news/711114/

相关文章:

  • 明日方舟游戏资源完整指南:如何高效获取1000+高清角色立绘与游戏数据
  • FloPy:Python地下水流建模的终极指南
  • 为什么99%的Python工程师还没用上Python 3.15的并行解释器?,从PEP 703到生产环境灰度部署全链路避坑手册
  • HarmonyOS 6 Counter组件使用示例文档
  • GitHub Actions自动化工作流实战:从CI/CD到容器化部署
  • 2026年4月温州日记本五金配件优质源头厂家综合** - 2026年企业推荐榜
  • OMR转换时间时区后返回
  • ROC与PR曲线:解决分类模型评估中的类别不平衡问题
  • 《100个“反常识”经验12:死锁日志怎么看?》
  • Python AI原生应用推理加速实战手册(PyTorch 2.4 + Inductor + vLLM深度调优全图谱)
  • 掌握this关键字
  • 物理AI推动人机协作迈向新阶段研究报告凯捷 2026_01
  • Windows Cleaner终极指南:三步解决C盘爆满与系统卡顿问题
  • 为什么92%的开发者配不稳Copilot Next自动化流?——源自Microsoft官方仓库commit日志的3大隐藏约束解析
  • 论文降重新纪元:书匠策AI,一键解锁学术纯净秘籍
  • CVPR2023 RIDCP论文精读:除了SOTA结果,它的‘可控先验匹配’设计思路能给你的项目什么启发?
  • Python自动化抢票终极指南:告别手速焦虑,3步轻松搞定大麦网热门演出
  • 云顶之弈悬浮辅助工具TFT Overlay:三步提升你的战术决策效率
  • AGV双锂电池系统厂家推荐(双电池/换电系统方案解析)【浩博电池】
  • 论文“瘦身”新秘籍:书匠策AI,一键解锁降重降AIGC新境界
  • Kaimon.jl:基于MCP协议实现AI助手与Julia运行时的深度集成
  • 常用16进制转换
  • 深度强化学习实战:从DQN到A3C,拆解智能体决策引擎核心原理
  • 抖音批量下载完整指南:快速掌握高效下载技巧
  • 《每日一命令12:kill——不只是杀进程这么简单》
  • 机器人双电池厂家推荐(双电池/热插拔系统解决方案)【浩博电池】
  • 医学影像报告自动生成技术:临床对比解码(CCD)详解
  • AI 系统的“可预测性”:我们真的能信任 AI 吗?
  • AutoHideCursor:自动隐藏鼠标光标,打造无干扰桌面工作环境
  • Windows任务栏透明美化终极指南:5分钟让桌面焕然一新的简单教程