每天学一个算法--单调栈(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:方向搞反

  • 左 → 右
  • 右 → 左

答案不同


教学总结

单调栈的本质是:

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

相关推荐
X journey1 天前
机器学习进阶(13):支持向量机SVM
算法·机器学习·支持向量机
洛水水1 天前
【力扣100题】30.二叉树的直径
算法·leetcode·职场和发展
叶帆1 天前
【YFIOs】Docker方式部署
运维·docker·容器
gihigo19981 天前
Bezier曲线曲面生成算法
算法
小猿姐1 天前
Clickhouse Kubernetes Operator 实测:哪种方案更适合生产?
运维·数据库·kubernetes
平行侠1 天前
024多精度大整数 - 突破硬件精度限制的任意精度运算
数据结构·算法
彩色的黑'''1 天前
[root@localhost ~]#,Linux系统的命令提示符为啥现在变成-bash-4.2#了,哪里设置的
linux·运维·bash
树下水月1 天前
文件分片上传接口(Easyswoole)被nginx拦截,并返回状态码400和408的抓包排查过程
运维·nginx
IronMurphy1 天前
【算法四十五】139. 单词拆分
算法
源远流长jerry1 天前
Linux 网络发送机制深度解析:从应用到网线
linux·服务器·网络·网络协议·tcp/ip