每天学一个算法--单调栈(Monotonic Stack)

📘 教案 08:单调栈(Monotonic Stack)


1️⃣ 先看一个真实问题(非常关键)

给你一个数组:

text 复制代码
[2, 1, 2, 4, 3]

问题:

对每个数,找到"右边第一个比它大的数"


手算一下(你脑子会这样想)

  • 2 → 右边第一个更大是 4
  • 1 → 右边第一个更大是 2
  • 2 → 右边第一个更大是 4
  • 4 → 没有 → -1
  • 3 → 没有 → -1

如果你写代码(暴力)

python 复制代码
for i in range(n):
    for j in range(i+1, n):
        if A[j] > A[i]:
            break

👉 时间复杂度:

O(n2)\]\[ O(n\^2) \]\[O(n2)


❗问题本质

你在重复做一件事:

"找右边第一个更大元素"


2️⃣ 单调栈就是为了解决这个

一句话:

单调栈 = 用一个"有序结构",避免重复比较


3️⃣ 核心直觉(最重要)

我们从左往右扫数组:

text 复制代码
[2, 1, 2, 4, 3]

我们维护一个东西:

👉 一个"还没找到答案的元素集合"


4️⃣ 一步一步看(这是核心)


Step 1:看 2

text 复制代码
stack = [2]

👉 还不知道右边谁比它大


Step 2:看 1

text 复制代码
stack = [2, 1]

👉 1 也没找到更大的


Step 3:看 2

来了关键点👇

👉 当前 2 > 栈顶 1

说明:

text 复制代码
1 的答案找到了 → 就是 2

👉 把 1 弹出去


现在继续:

text 复制代码
stack = [2]

当前 2 == 栈顶 2 → 不弹

text 复制代码
stack = [2, 2]

Step 4:看 4(高潮)

👉 4 > 2 → 弹

👉 4 > 2 → 再弹

text 复制代码
2 → 4
2 → 4

👉 全部解决

text 复制代码
stack = []

然后:

text 复制代码
stack = [4]

Step 5:看 3

text 复制代码
stack = [4, 3]

最后

栈里剩下的:

text 复制代码
4, 3

👉 没有更大的 → -1


🔥 到这里核心已经懂了

谁被弹出,谁的答案就确定了


5️⃣ 单调栈到底是什么?

现在给定义(你已经能理解了)


定义:

一个"保持单调性"的栈结构


两种类型:


🔹 单调递减栈(常用)

栈内从底到顶:

text 复制代码
大 → 小

👉 用来找:

右边第一个更大元素


🔹 单调递增栈

text 复制代码
小 → 大

👉 用来找:

右边第一个更小元素


6️⃣ 标准模板(你可以直接教人)


找"右边第一个更大"

python 复制代码
stack = []
res = [-1]*n

for i in range(n):
    while stack and A[i] > A[stack[-1]]:
        idx = stack.pop()
        res[idx] = A[i]
    stack.append(i)

注意:

👉 栈里存的是"下标",不是值


7️⃣ 为什么一定是 O(n)


关键:

每个元素只会:

  • 入栈一次
  • 出栈一次

👉 总操作:

O(n)\]\[ O(n) \]\[O(n)


8️⃣ 常见应用(非常重要)


8.1 下一个更大元素

👉 刚讲的


8.2 柱状图最大矩形(经典难题)


8.3 股票问题

👉 找最近更大/更小


8.4 温度问题(LeetCode经典)


9️⃣ 单调栈最本质一句话

它不是"栈",而是"用栈维护顺序关系"


10️⃣ 常见错误


❌ 错误1:搞不清什么时候弹

记住一句:

👉 当前元素更强(更大/更小) → 弹栈


❌ 错误2:存值还是下标

👉 一律存下标


❌ 错误3:方向搞反

  • 左 → 右
  • 右 → 左

答案不同


教学总结

单调栈的本质是:

用一个"有序结构"一次性解决所有"下一个更大/更小"的问题

相关推荐
hhb_6182 小时前
Linux底层运维自动化挂载与磁盘分区实战指南
linux·运维·自动化
ZPC82102 小时前
ROS2 速度远快于 UDP的完整方案(同机节点)
人工智能·算法·计算机视觉·机器人
SpikeKing2 小时前
Server - 配置 SQLBot 智能问数项目
运维·server·sqlbot
khalil10202 小时前
代码随想录算法训练营Day-34动态规划03 | 01背包问题 二维、01背包问题 一维、416. 分割等和子集
数据结构·c++·算法·leetcode·动态规划·背包问题·01背包
华清远见IT开放实验室2 小时前
AI 算法核心知识清单(深度实战版2)
人工智能·深度学习·算法·机器学习·ai·模型训练
爱学习的小囧2 小时前
ESXi 开启 Secure Boot 后驱动签名验证失败完整处置教程:合规修复与临时测试方案全解
服务器·数据库·esxi·虚拟化
cui_ruicheng2 小时前
Linux库制作与使用(二):ELF文件与链接过程
linux·运维·服务器
怀旧,2 小时前
【Linux系统编程】18. Linux进程信号(上)
linux·运维·服务器
舰长1152 小时前
Windows服务器修改默认远程端口3389
运维·服务器