D
AI
学习工作台
8 周后端冲刺2026-05-222 分钟阅读

栈与队列

单调栈、单调队列、BFS 与表达式求值

8周冲刺week2队列单调栈记笔记标记疑惑

栈:LIFO 与典型场景

栈适合 最近相关性:括号匹配、路径撤销、DFS 迭代、表达式求值。

有效括号

def is_valid(s):
    stack = []
    pairs = {')': '(', ']': '[', '}': '{'}
    for ch in s:
        if ch in '([{':
            stack.append(ch)
        elif not stack or stack.pop() != pairs[ch]:
            return False
    return not stack

逆波兰表达式:遇数字入栈,遇运算符 pop 两个操作数计算再 push。

单调栈

维护栈内元素单调(增或减),用于 Next Greater Element柱状图最大矩形接雨水

def daily_temperatures(temps):
    n = len(temps)
    ans = [0] * n
    stack = []  # 存下标,温度递减
    for i, t in enumerate(temps):
        while stack and temps[stack[-1]] < t:
            j = stack.pop()
            ans[j] = i - j
        stack.append(i)
    return ans

每元素最多入栈出栈一次,总 O(n)

队列与 BFS

队列 FIFO,用于 层序遍历无权图最短路

from collections import deque

def level_order(root): if not root: return [] q = deque([root]) out = [] while q: level = [] for _ in range(len(q)): node = q.popleft() level.append(node.val) if node.left: q.append(node.left) if node.right: q.append(node.right) out.append(level) return out

记录 len(q) 可分层;多源 BFS 初始全部入队。

单调队列

滑动窗口最值: deque 存 下标,队头对应当前窗口最大值,入队前从队尾弹出更小元素。均摊 O(1),总 O(n)。

适用于「滑动窗口最大值」「跳跃游戏 III 变体」。

栈与队列互实现

  • 两个栈实现队列(见 flashcard)。
  • 一个队列实现栈:入队后把前面元素依次移到队尾,使新元素在队头。
面试常考均摊分析,说明为何不是每次 O(n)。

与 Week 2 树章节衔接

week02-tree-dfs-bfs 中 DFS 可用栈模拟递归,BFS 即队列。图论 Week 3 week03-backtracking-graph 会扩展拓扑排序(入度 + 队列)。

练习建议

单调栈 3 题:每日温度、柱状图矩形、接雨水。BFS 2 题:二叉树层序、网格岛屿数量。写代码前先声明栈/队列存的是 值还是下标

实战巩固与面试表达

本篇属于 8 周冲刺 week02-stack-queue 主题。复习时先闭卷回答 frontmatter 中三张 flashcard,再展开口述两个「为什么」:为什么这种方案能 work、边界失败时如何降级。与相邻章节对照:算法篇强调复杂度与模板,Go 篇强调工程默认写法,中间件篇强调线上故障案例。

动手与自检清单

用 25 分钟限时做 1 道相关练习题或画出一张架构/数据结构示意图;用 5 分钟写 STAR 片段说明你在项目里是否用过类似技术。记录 3 个面试追问及你的标准答法,存入 /zh/notebook/master-plan 笔记。若某点不熟,回到对应 /chapters 交互 Lab 重新走一遍流程,比死记卡片更有效。

易错点提醒

避免只背名词不会画图;避免只说优点不谈 trade-off(性能、一致性、运维成本至少提一项);避免把学习 Demo 说成百万 QPS 生产。回答时使用「场景 → 方案 → 结果 → 反思」四段式,体现工程成熟度。

知识卡片

问题

单调递减栈求「下一个更大元素」怎么做?

点击翻转查看答案

答案

从左到右:当前元素 x 大于栈顶则栈顶出栈并记录 x 为栈顶答案;再将 x 下标入栈。栈维护递减序列。

问题

用两个栈实现队列的关键?

点击翻转查看答案

答案

in 栈负责入队,out 栈负责出队;仅当 out 空时把 in 全部倒入 out,保证 FIFO 均摊 O(1)。

问题

BFS 与 DFS 在树/图上的结构差异?

点击翻转查看答案

答案

BFS 用队列按层扩展,最短步数(无权图);DFS 用栈/递归深入,路径、连通分量、回溯。