在 Google 面试前,我花了三个月刷 LeetCode,做了 247 道题。结果面试官问了一道图遍历问题——我之前明明见过——我却卡住了,因为我记住的是解法,而不是模式。
转机出现在我停止把每道题当作独立问题,开始构建一套 30 种模式的记忆卡片。两个月后,我能在读完新题目的 30 秒内识别出正确方法。模式识别变成了自动反应。
TL;DR
大多数 LeetCode 问题都属于约 30 种可识别的模式(滑动窗口、双指针、单调栈等)。间隔重复记忆卡片帮助你内化这些模式,在面试中瞬间识别它们。使用两种卡片类型:概念卡片(何时使用该模式)和模板卡片(代码框架)。每天复习 2-3 个月,让模式匹配成为自动反应。
为什么模式识别胜过题海战术
LeetCode 有 2900+ 道题,你不可能全部记住。但关于专家问题解决的研究表明,大师们不是记忆解法——他们识别问题结构。
Chase 和 Simon 在 1973 年的研究发现,国际象棋大师在看 5 秒钟后能重构棋盘位置,但仅限于棋子形成合法棋局模式时。如果随机打乱棋子,大师的表现并不比初学者好。他们通过刻意练习建立了约 50,000 种棋局模式的心理库。
编程面试的原理相同。当你看到"找大小为 k 的子数组的最大和",你的大脑应该立即触发:滑动窗口,固定大小。当你看到"合并 k 个有序链表",你应该想到:最小堆,k 路归并模式。
问题在于:随机做 200 道 LeetCode 题并不能高效建立这个模式库。你需要间隔重复将模式从短期识别转化为长期自动化。
覆盖 80% 面试题的 30 种核心模式
在分析了 500+ 道标记为"Google"、"Meta"和"Amazon"的 LeetCode 问题后,我总结出 30 种反复出现的模式。按类别分类如下:
数组与字符串模式(8 种)
- 滑动窗口(固定大小) — 大小为 k 的子数组最大和
- 滑动窗口(可变大小) — 无重复字符的最长子串
- 双指针(相向而行) — 有序数组的两数之和、盛最多水的容器
- 双指针(同向而行) — 删除有序数组中的重复项
- 前缀和 — 和为 k 的子数组
- Kadane 算法 — 最大子数组和
- 荷兰国旗 — 颜色分类(三路划分)
- 循环排序 — 在 [0, n] 中找缺失数字
链表模式(3 种)
- 快慢指针 — 检测环、找中间节点
- 分组反转 — K 个一组翻转链表
- 合并模式 — 合并两个有序链表、合并 k 个有序链表
栈与队列模式(4 种)
- 单调栈(递增) — 下一个更大元素
- 单调栈(递减) — 柱状图中最大的矩形
- 单调队列 — 滑动窗口最大值
- 表达式求值 — 有效的括号、计算器问题
树与图模式(7 种)
- DFS(前序/中序/后序) — 树的遍历、路径总和
- BFS(层序) — 二叉树的层序遍历、最小深度
- 二叉搜索树性质 — 验证 BST、第 k 小的元素
- 最近公共祖先 — 二叉树/BST 的 LCA
- 图 DFS(回溯) — 岛屿数量、单词搜索
- 图 BFS(最短路径) — 单词接龙、腐烂的橘子
- 拓扑排序 — 课程表、火星词典
动态规划模式(5 种)
- 一维 DP(线性扫描) — 打家劫舍、爬楼梯
- 二维 DP(网格) — 不同路径、最小路径和
- 背包(0/1) — 分割等和子集
- 背包(完全) — 零钱兑换
- LCS/LIS 模式 — 最长公共子序列、最长递增子序列
二分查找模式(3 种)
- 经典二分查找 — 在有序数组中搜索
- 旋转数组搜索 — 寻找最小值、搜索目标
- 答案空间二分 — Koko 吃香蕉、运送包裹的能力
两种卡片类型:概念 vs 模板
有效的 LeetCode 模式记忆卡片需要两个层次:
1. 概念卡片(何时使用该模式)
正面:
什么时候应该使用单调栈?
背面:
- 需要为每个元素找下一个更大/更小的元素
- 需要在类似柱状图的结构中找最大矩形
- 问题涉及从左到右处理元素时保持顺序
关键信号:
- "下一个更大/更小"
- "最大/最小矩形/面积"
- 需要 O(n) 时间解决看似 O(n²) 的问题
示例问题:
- 下一个更大元素 I/II (LC 496, 503)
- 柱状图中最大的矩形 (LC 84)
- 接雨水 (LC 42)
这种卡片类型训练模式识别——让你在面试的前 30 秒识别出正确方法的技能。
2. 模板卡片(代码框架)
正面:
单调栈模板(递增)
背面:
def next_greater_element(nums):
result = [-1] * len(nums)
stack = [] # 存储索引
for i in range(len(nums)):
# 弹出较小元素
while stack and nums[stack[-1]] < nums[i]:
idx = stack.pop()
result[idx] = nums[i]
stack.append(i)
return result关键不变量: 栈保持递增顺序(从底到顶)
模板卡片提供代码框架,让你不必在面试压力下重新发明轮子。你仍需要根据具体问题调整模板,但你是从 70% 完成度开始,而不是从零开始。
如何构建你的模式卡组
步骤 1:从 10 种高频模式开始
不要试图一次学习全部 30 种模式。从出现在 50%+ 中等难度问题中的模式开始:
- 滑动窗口(可变大小)
- 双指针(相向而行)
- 快慢指针
- 单调栈
- DFS(树/图)
- BFS(层序)
- 二分查找(经典)
- 一维 DP
- 哈希表实现 O(1) 查找
- 前缀和
每种模式创建 2 张卡片(1 张概念 + 1 张模板)= 20 张卡片起步。
步骤 2:遇到时添加模式变体
在熟悉核心 10 种模式后,扩展到变体:
- 滑动窗口(固定大小)——单独的卡片,因为逻辑不同
- 双指针(同向而行)——不同于相向而行的方法
- 单调栈(递减)——与递增相反的不变量
我使用 SmartRecall 的标签系统对变体分组:#滑动窗口、#双指针、#单调栈。这让我在需要复习时能一起回顾某个模式的所有变体。
步骤 3:将卡片链接到实际问题
在每张概念卡片的背面,列出 3-5 道使用该模式的 LeetCode 问题。复习卡片时,选一道题做,验证你能应用该模式。
示例工作流:
- 复习"滑动窗口(可变大小)"概念卡片
- 卡片列出:LC 3、LC 76、LC 424、LC 904
- 在 10 分钟内解决 LC 3(无重复字符的最长子串)
- 如果卡住,复习模板卡片
- 根据识别模式的速度将概念卡片标记为"良好"或"困难"
这将被动复习转化为主动练习。
模式掌握的间隔重复计划
模式识别需要过度学习——你需要在 2-3 个月内复习每个模式 15-20 次才能使其自动化。
阶段 1:初始学习(第 1-2 周)
- 每周添加 5 种新模式(10 张卡片:5 张概念 + 5 张模板)
- 每天复习
- 每种模式做 2-3 道题验证理解
- 预期复习时间:每天 20-30 分钟
2 周后,你的卡组中将有 20 种模式(40 张卡片)。
阶段 2:巩固(第 3-8 周)
- 停止添加新模式
- 让 SRS 算法安排复习间隔
- 专注于结合多种模式的问题
- 预期复习时间:每天 15-20 分钟
SmartRecall 的 FSRS 算法会以递增间隔显示每张卡片:1 天 → 3 天 → 7 天 → 14 天 → 30 天。你感到困难的卡片会更快回来。
到第 8 周,你应该能在读完问题描述的 10 秒内识别出前 20 种模式。
阶段 3:高级模式(第 9-12 周)
- 添加剩余 10 种模式(DP 变体、高级图算法)
- 继续每日复习
- 练习模拟面试,在压力下测试模式识别
制作模式记忆卡片的常见错误
错误 1:制作解法卡片而非模式卡片
错误做法:
正面:"如何解决 LC 3(无重复字符的最长子串)?"
背面:[完整解法代码]
这教你记住一道题,而不是识别模式。
正确做法:
正面:"什么时候应该使用滑动窗口(可变大小)?"
背面:[模式识别触发器 + 5 个示例问题,包括 LC 3]
错误 2:模板卡片没有不变量
没有关键不变量的代码模板只是语法。始终包括:
- 数据结构维护什么(例如,"栈按递增顺序存储索引")
- 何时扩展/收缩窗口
- 循环不变量保证什么
错误 3:不将卡片与练习关联
仅靠记忆卡片不会让你成为强大的问题解决者。复习工作流应该是:
- 看到概念卡片
- 回忆模式触发器
- 使用该模式解决一道题
- 根据识别速度给卡片评分
我 60% 的复习时间花在实际编码上,而不只是阅读卡片。
跟踪进度:何时模式识别变成自动反应
当出现以下情况时,你就知道模式已经内化:
- 读完问题后 30 秒内能识别出正确模式
- 能在 2 分钟内凭记忆写出模板框架
- 开始在没有明确提及的问题中看到模式(例如,"找最短转换序列"→ BFS 最短路径)
对我来说,这花了 11 周的每日复习。我在电子表格中跟踪"模式识别时间":
- 第 1 周:平均 3-4 分钟识别模式
- 第 4 周:平均 1-2 分钟
- 第 8 周:平均 20-30 秒
- 第 11 周:平均 10-15 秒
一旦你稳定在 30 秒以内,就可以参加真实面试了。
将模式记忆卡片与 LeetCode 练习结合
这是我面试准备期间的日常安排:
上午(30 分钟):
- 在 SmartRecall 中复习模式记忆卡片
- 对每张概念卡片,解决一道关联问题
- 如果 10 分钟内解决不了,复习模板卡片
晚上(60 分钟):
- 解决 2-3 道新的 LeetCode 问题
- 解决后,识别问题使用了哪些模式
- 如果没有立即识别出模式,在相关概念卡片上添加笔记
每周(2 小时):
- 与朋友进行模拟面试
- 复习在压力下未能识别的模式
- 在 SmartRecall 中增加这些卡片的复习频率
这种间隔重复(上午)和刻意练习(晚上)的结合既培养识别速度又培养应用技能。
超越 30 种模式:何时停止添加卡片
你不需要记住所有发明过的算法。我概述的 30 种模式覆盖:
- 80% 的 LeetCode 中等问题
- 60% 的 LeetCode 困难问题
- 90% 的实际 FAANG 面试问题(基于 Glassdoor 数据)
掌握这 30 种后,专注于:
- 解题速度 — 你能在 20-25 分钟内实现该模式吗?
- 沟通能力 — 你能向面试官解释你的模式选择吗?
- 边界情况 — 你能识别何时需要修改模式吗?
我仍然使用 SmartRecall 维护我的模式库(每隔几天复习 10 分钟),但不再添加新模式。目标是自动化,而不是百科全书式的知识。
从 10 种模式开始,每天复习,跟踪识别速度
模式识别是刷 500 道题仍在面试中卡壳,与战略性地做 150 道题就能自信走进面试之间的区别。
用两种卡片类型构建你的卡组:概念卡片用于识别触发器,模板卡片用于代码框架。从 10 种高频模式开始,每天复习 8-12 周,跟踪你的识别时间。
当你能在 30 秒内识别出正确模式时,你不仅为面试做好了准备——你还建立了一个心理框架,让你在职业生涯的余生中成为更快的问题解决者。
即使我不再面试,我仍在 SmartRecall 中保持模式卡组活跃。它已成为我的外部算法大脑——每当我需要解决映射到经典模式的生产问题时,它总在那里。

