大多数”公司 X 的 LeetCode”清单都是从聚合站抓来的 250 道题,按标签分组,没有任何注释。 你做完”two pointers”,清单对下一步该做什么、为什么,一句话都没有。这份清单是约 70 道 核心题,排成一条学习路径:十一个阶段,每一段都复用上一段打造的工具,每一段都有一条 告诉你何时可以往前走的标准,以及一句告诉你下一段为什么接在这里的过渡。
校准假设:你的目标是中到资深级别的面试(Meta E4/E5、Google L4/L5、 Amazon SDE II/III,或同等级别)。应届生面试考的是同样阶段的更简单切片。搭配 coding round 指南 一起看,了解进了考场之后如何把控时间。
这份清单是怎么组织的
有两种顺序很重要,而且它们不是同一个顺序:
- 学习顺序——下面的路径。从基石开始,每一段都依赖前一段:stage 1 的 window 就是 stage 0 的 two pointers 改成同向走;stage 4 的树,就是 stage 3 的 stack 被递归隐式地替你维护;stage 10 的对象设计,由前面各段的 linked list、heap 和 Trie 组装而成。不要打乱阶段顺序——一道题让你觉得做不出来,通常意味着你跳过了它所 依赖的那一段。
- 识别顺序——在考场上面对一道从没见过的题时,你按顺序问自己的那些问句。也就是路径 之后的问题识别框架。每一段都标注了它教的类别,所以走完这条路径, 你已经从内部见过每一个类别是怎么被识别出来的。
这份清单的早期版本把两者混在了一起:各节按识别顺序排列,结果把 Object Design—— 收尾的那一段——排在第一,把基石排在第六。识别是你路由一道题的方式;拿它当学习顺序 并不合适。
刻意排除在外的:位运算、数学技巧、segment tree,以及 hard DP 的长尾。它们真实存在但很 罕见,在接下来里排好了优先级,让你在路径跑顺 之后清楚地知道边际的那一小时该花在哪里。
从这里开始
| 如果你需要…… | 去看 |
|---|---|
| 用来练习的题目(你在这里) | 本清单 |
| 如何把控整场面试 | 指南:大厂资深 coding 面试 |
| Amazon 特有的 coding 标准 | 指南:Amazon 的 Logical & Maintainable |
| 完整的 12 周计划 | 计划:资深后端面试准备 |
路径一览
| 阶段 | 学什么 | 类别 | 题数(+ 延伸题) | 何时往前走 |
|---|---|---|---|---|
| 0 | 热身:hash、stack、linked list、对撞指针 | Transformation | 7 + 1 | 每道 ≤10 分钟,含测试 |
| 1 | Sliding window | State Maintenance | 5 | 3 在 8 分钟内;能说出 window 的不变式 |
| 2 | Prefix sum 与 hash map 状态 | State Maintenance | 4 | 写代码前能说出要存的状态 |
| 3 | Monotonic stack | State Maintenance | 5 | 能说清为什么每个元素只入栈、出栈一次 |
| 4 | 树的递归与 BFS | Traversal | 6 | 124 在 ≤25 分钟内写干净 |
| 5 | 图与网格 | Traversal | 5 + 1 | 能带着理由说出选 BFS 还是 DFS |
| 6 | 区间与 heap | Ordering | 7 | 带着理由在 heap、quickselect、sort 之间选择 |
| 7 | 二分查找与细致的算术 | Search · Transformation | 4 + 2 | 33 零 off-by-one,15 分钟内 |
| 8 | 动态规划 | Decision / Optimization | 5 + 2 | 写之前先说出 dp[i] 的含义 |
| 9 | 回溯 | Enumeration | 7 + 1 | 写代码前说出剪枝规则 |
| 10 | 对象设计(收尾) | Object Design | 6 + 1 | LRU Cache 从白纸开始 ≤20 分钟 |
| 11 | 每段一道 hard 复练 | 全部 | 12 | 按目标公司的面试形态,两场冷启动 mock 通过 |
全程的资深标准时间:easy ≤10 分钟,medium ≤20–25,hard ≤35–40,均含测试和复杂度分析。”+ 1” 指的是某道题说明里点名的延伸题(例如 141 之后的 142)——主题写干净之后再做一次。
路径
Stage 0 · 热身:hash、stack、linked list、对撞指针
类别: Transformation(指针重连),外加第一批 State Maintenance 练习。 依赖: 无——这是地板。
CtCI 时代的老经典,至今仍是电话面的开场题。一次计时坐下来把它们刷完。重点不是学会它们, 而是确认没有一道能让你措手不及——热身题失手的代价,比错过一道 hard 更大。
- 1. Two Sum — 人人都见过的 hash map 一行题。90 秒解完就往前走;它唯一的作用是别让你措手不及。
- 20. Valid Parentheses — 经典的 stack 热身;stage 3 的 1249 就是这道题再多一个决策。
- 21. Merge Two Sorted Lists — 双指针合并,stage 6 的 23. Merge k Sorted Lists 用一个 heap 把它推广开。先把这道练到不假思索。
- 88. Merge Sorted Array — 从后往前原地合并。一道看似简单却常见的 Meta/Amazon 热身,“从尾部填”这个技巧 就是全部信号。
- 206. Reverse Linked List — 史上被问得最多的热身题。迭代和递归两种写法,都要在五分钟内完成;一半的 linked list 追问都建立在它之上。
- 141. Linked List Cycle — Floyd 快慢指针。追问 142(找环的起点)才是 资深标准下真正被问的版本。
- 125. Valid Palindrome — 两个指针从两端向中间收拢。stage 9 会以 680 的形式回到它,那是 Meta 的最爱。
Caution
常见错误:
在 linked list 变换中,还没保存就先改了 next,结果丢了节点。把指针画出来,用 dummy head,按正确的顺序推进。这些题看着简单,但在一道”easy”热身题上丢一个指针,就是当场 no-hire。
何时往前走: 上面每道题都能在 ≤10 分钟内连测试一起完成,并且 234. Palindrome Linked List ——它把快慢指针、反转和对撞比较组合在一起——能冷启动一次写干净。
下一段 → 在 125 里,两个指针相向而行。让它们同向走,两者之间的间隔就是一个 window。
Stage 1 · Sliding window
类别: State Maintenance。依赖: stage 0 的 two pointers。
大多数面试的第一道 coding 题出自 stage 1–3。标准是 12–15 分钟内写出干净代码;25 分钟 很可能挂掉这一轮,即使解法能跑。按顺序做——每一道都在模板上加一个新想法。
- 3. Longest Substring Without Repeating Characters — 经典的可变 window,到处都考。如果你无法在 8 分钟内写出模板,路径后面的题帮不了你。 先做这道。
- 567. Permutation in String — 带字符计数的固定大小 window。新增的想法是”每一步以 O(1) 比较两个频率表”。
- 438. Find All Anagrams in a String — 还是 567,但要收集每一个匹配。在 Meta 高频;如果 567 写干净了,这道只要五分钟。
- 76. Minimum Window Substring — hard 级的经典:扩张直到合法,在合法时收缩。是所有”包含 X 全部元素的最小 window” 题的模板。
- 424. Longest Repeating Character Replacement —
window 的合法性是一个公式(
length − maxCount ≤ k),而不是一个集合。把它当作 这一段的考试冷启动去做:它检验的是你理解了模板,还是背下了四道题。
何时往前走: 3 在 8 分钟以内,并且对任何 window 题,你都能在写循环之前用一句话说出 不变式——“window 里永远没有重复字符”。
下一段 → window 只在”扩大它只会让条件单向变化”时才成立。一旦允许负数,这就失效了—— 你需要记住每一个前缀,而不只是当前这个 window。
Stage 2 · Prefix sum 与 hash map 状态
类别: State Maintenance。依赖: stage 1——window 的单调性失效时,就用这个。
一次线性扫描,一个选对了的状态。技能在于写循环之前先说出这个状态——一个 prefix sum 的 map、一个派生 key、一个 running minimum。
- 560. Subarray Sum Equals K — prefix sum + HashMap。经典的”这其实不是 window”陷阱:照 stage 1 去做,负数会让你 翻车。认清为什么,就是这一课。
- 49. Group Anagrams — 用派生 key(排序后的字符串或字符计数)的 hash map。考察你能否设计出正确的 key; 可迁移到所有”按属性分组”的题。
- 238. Product of Array Except Self — 不用除法的 prefix/suffix product。最干净的”在两个方向上维护状态”。
- 121. Best Time to Buy and Sell Stock — 单遍历跟踪最小值。候选人会过度设计;好的解法是 10 行。
Caution
常见错误: 在不变式不成立时硬套 sliding window。当一个 window 需要不可预测地既扩又缩,这就是信号:它不是 window——它是前缀状态。
何时往前走: 每道题都能在写代码前用一句话说出要存的状态(“迄今为止每个 prefix sum 出现的次数”),并且做 560 时不再先去试 window。
下一段 → 121 为整个数组只保留一个 running value。当每一个元素都需要自己的答案—— “这一天之后下一个更暖的日子”——你就得把还没得到答案的元素暂存起来,直到答案出现。
Stage 3 · Monotonic stack
类别: State Maintenance。依赖: stage 0 的 stack(20)和 stage 2 的单遍历状态。
一个在 Meta、Amazon 和 Google 出现频率上升的模式。stack 里存的是还在等答案的元素, 保持有序,这样每个元素只入栈一次、出栈一次——总共 O(n)。
- 739. Daily Temperatures — 经典的”下一个更大元素”。在 Amazon 高频。在这里学会模板。
- 901. Online Stock Span — 同一个 stack,但写成一个流式的类:一次回答一个元素。是 stage 10 对象设计的第一次预演。
- 84. Largest Rectangle in Histogram — 更难的 monotonic stack 经典。理解为什么出栈能给出矩形的宽度,也就解锁了 42 的 stack 解法。
- 42. Trapping Rain Water — 资深标准下 Amazon 和 Google 的常客。做两遍:带 running max 的对撞指针(stage 0), 然后用 stack。说出两者之间的权衡,就是资深信号。
- 1249. Minimum Remove to Make Valid Parentheses — 高频,尤其在 Meta:stage 0 的 20 再加上”删掉哪些下标”。它的资深追问 301 在 stage 9 等着你。
何时往前走: 你能说出 stack 里存的是什么、为什么每个元素最多入栈出栈一次,并且 84 能在 ≤35 分钟内完成。
下一段 → 一个存放待处理工作的 stack,正是递归替你隐式维护的东西。树就是用这种写法 最自然的地方。
Stage 4 · 树的递归与 BFS
类别: Traversal。依赖: stage 3——调用栈就是那个 stack。
第二轮 coding 通常出自 stage 4–5。标准变了:不再是”12 分钟写干净”,而是”25 分钟内写对, 并对权衡有合理的讨论”。
- 543. Diameter of Binary Tree — “向上返回一个值,在全局记账另一个值”这一模式的最简形式。从这里开始。
- 124. Binary Tree Maximum Path Sum — 543 的模式,更难:负值让”向上返回什么”变得不再显然。在 Google 和 Meta 高频。
- 236. Lowest Common Ancestor of a Binary Tree — 递归分治:每棵子树报告它找到了什么。变体(带 parent 指针的 LCA)是常见追问。
- 102. Binary Tree Level Order Traversal — 树的 BFS 模板。许多树题都归约为”带记账的层序遍历”,它也是树序列化(stage 11 的 297) 的骨架。
- 199. Binary Tree Right Side View — 层序 BFS 或前序 DFS。两种都练——面试官常在你给出第一种解法后要另一种。
- 314. Binary Tree Vertical Order Traversal — 那道 Meta 树题:带列追踪的 BFS。它出名到面试官能分辨出你是背的还是推出来的—— 第一次就要写干净。
何时往前走: 124 在 ≤25 分钟内写干净,并且你能从白纸写出 DFS 返回值模板和 BFS 队列模板。
下一段 → 树是只有一个根、没有环的图。去掉这两个保证——加一个 visited 集合,允许多个
起点——你就有了图。
Stage 5 · 图与网格
类别: Traversal。依赖: stage 4 的 DFS 和 BFS 模板。
- 200. Number of Islands — 经典的网格遍历,到处都考。用 DFS 和 BFS 各解一遍,你就覆盖了大多数网格题。
- 994. Rotting Oranges — 多源 BFS,Amazon 的最爱。“从所有源点同时开始 BFS”可迁移到大多数网格最短时间题。
- 133. Clone Graph — 带一个从原节点到副本的 HashMap 的遍历。克隆只是记账;陷阱在于把递归与迭代的权衡讲错。
- 207. Course Schedule — 环检测 / 拓扑排序,Google 和 Amazon 的常客。掌握 Kahn 算法(在入度上做 BFS); 追问 210 要求给出顺序本身。
- 323. Number of Connected Components in an Undirected Graph — BFS/DFS 或 union-find。练 union-find 版本:15 分钟就能学会,而它在 Google、Meta 和 Databricks 出现得出人意料地频繁。
Tip
为什么 BFS vs DFS 是真正的选择: 可达性和连通分量默认用 DFS(代码更短);一旦题目暗示距离或层级——无权网格上的最短路、“所有橘子腐烂需要几分钟”、按层输出——就立刻换成 BFS。说出你为什么选其中一个,才是信号;凭习惯选不是。
何时往前走: 写代码前你能带着理由说出选 BFS 还是 DFS,并且不查任何资料就能写出 Kahn 算法。
下一段 → BFS 按距离的顺序处理节点。当真正重要的顺序是别的——最早结束时间、最高优先级、 最近的 k 个——你就排序,或者维护一个 heap。
Stage 6 · 区间与 heap
类别: Ordering。依赖: stage 0 的合并(21)和 stage 5 的”按顺序处理”直觉。
正确性取决于按特定顺序看到元素。强的候选人在这里靠选结构——sort、heap 还是 quickselect——并说出理由来拉开差距。
- 56. Merge Intervals — 经典区间题,每家公司都高频。排序 + 线性合并。
- 57. Insert Interval — 输入已经有序时的 56:不用排序,分三段处理。
- 435. Non-overlapping Intervals — 按结束排序,而不是开始。为什么这是正确的贪心,就是整道题。
- 253. Meeting Rooms II — 在结束时间上建 min-heap:“最早空出来的结束时间是哪个” → heap。从区间通往 heap 的桥。
- 973. K Closest Points to Origin — 经典的 top-k。用大小为 k 的 heap 和 quickselect 各解一遍;流式数据的追问其实是在问 你为什么选了 heap。
- 215. Kth Largest Element in an Array — quickselect 是经典答案。追问总是”怎么避免 O(n²)?“——随机化 pivot。在被问之前就说出来。
- 23. Merge k Sorted Lists — stage 0 的 21 加上一个存放各链表头的 heap。Amazon 和 Google 的常客;k 路归并模板也是 外部排序追问的基础。
Note
面试信号: 对 top-k,写出大小为 k 的 heap,并且说出 quickselect——然后说清什么时候选哪个:流式数据或 k ≪ n 时用 heap,一次性的内存数组用 quickselect。一个 heap 就够时却去全排序,读起来就是初级。
何时往前走: 每道题你都能说出自己选了 sort、heap、quickselect 中的哪个,以及另外两个 会付出什么代价。
下一段 → 数据一旦有序,你就不必看全部——二分查找每一步扔掉一半。同样的技巧适用于任何 有序的空间,包括一个由可能答案组成的空间。
Stage 7 · 二分查找与细致的算术
类别: Search,外加 Transformation。依赖: stage 6 的有序数据和 stage 2 的 prefix sum(528)。
最容易因为一个笔误挂掉的模式,也是最值得背熟的干净模板。两道字符串算术题放在这里,是因为 它们考的是同一件事:在计时下精确处理边界。
- 33. Search in Rotated Sorted Array — 经典的”带变化的二分查找”,到处都考。带重复元素的变体 81 是常见追问。
- 528. Random Pick with Weight — stage 2 的 prefix sum,然后在上面二分查找。在 Meta 高频;准备阶段就占了一半。
- 50. Pow(x, n) — 每一步把指数减半:二分查找的
减半思想,用在计算上。容易出 bug;练负数
n的边界情况。 - 415. Add Strings — 手动处理进位的算术
(不用
BigInteger)。常见热身题,追问通常是 43. Multiply Strings。
Caution
常见错误:
边界约定不一致导致 off-by-one 和死循环。选定一种——[lo, hi] 闭区间或 [lo, hi) 半开区间——并在整个解法里坚持。大多数”二分查找很简单”的失败,都是一个 < 与 <=,或一个与约定不匹配的 mid ± 1。
何时往前走: 33 在 15 分钟内零 off-by-one,并且写 mid 之前你能说出自己的边界约定。
下一段 → 二分查找之所以成立,是因为有一半可以安全地扔掉。当没有哪个选择能被扔掉——每一个 都会改变之后的可能性——你就转而保存子问题的答案。
Stage 8 · 动态规划
类别: Decision / Optimization。依赖: stage 4 的递归(自顶向下的 DP 就是递归 加缓存)。
比互联网所暗示的更小的一片。每家公司都会问一些 DP;没有哪家主流面试会问最难的那一层。 下面每种形态一道题,就覆盖了大部分会出现的内容——按这个顺序,每一道增加一个维度。
- 70. Climbing Stairs — 带两个状态记忆的 1D DP。很简单,但它是之后一切的框架。
- 198. House Robber — 最干净的取/不取决策; 环形变体 213 是合理的追问。
- 62. Unique Paths — 第一张 2D 表; 带障碍的变体 63 顺势而出。
- 322. Coin Change — 完全背包。把自底向上 的表内化;计时下你写的是迭代版。
- 139. Word Break — 在字符串上做 DP,配合 hash set 查询。通往 stage 9 的桥。
Tip
从递推式开始,而不是从表开始: 任何 DP 的难点都在于说出状态和转移——“dp[i] 是什么意思,它怎样由更早的项构建出来?“写代码之前先把这句话说出来。递推式对了,表自然就出来了。
何时往前走: 每道题写代码前你都能说出 dp[i] 的含义和转移,并且 322 能用自底向上的
写法在 ≤25 分钟内完成。
下一段 → 139 问的是字符串能不能被切分。它的姊妹题问的是所有切分方式——一旦你必须 列出全部答案,就没法把它们压缩进一张表;你得去枚举。
Stage 9 · 回溯
类别: Enumeration。依赖: stage 8 的 139 和 stage 4 的递归。
答案是每一种合法的配置。把模板过一遍就够了;资深标准下的变体考的是剪枝,而不是稀奇古怪的谜题。
- 17. Letter Combinations of a Phone Number — 最友好的回溯题,也是常见热身。在这里学会”选择 / 探索 / 撤销”的形状。
- 78. Subsets — 经典模板。用 include/exclude 递归和 5 行的 bitmask 版本各解一遍——面试官会记住第二种。
- 46. Permutations — 原地交换的版本最干净; 带重复元素的变体 47 是常见追问,也是 第一条真正的剪枝规则。
- 140. Word Break II — stage 8 的 139,现在要列出每一种切分:带记忆化的回溯。DP 与枚举交汇的那个点。
- 212. Word Search II — 网格上的回溯,用 Trie 剪枝。资深面试级别。
- 301. Remove Invalid Parentheses — stage 3 的 1249,现在要返回所有最少删除的答案。一道 Meta 最爱题的资深追问。
- 680. Valid Palindrome II — stage 0 的 125,外加最多删一个字符的额度:一个你最多只能走一次的分支。很短,但 Meta 用它 来考你能不能干净地分支。
Note
面试信号: 枚举题上的资深动作是剪枝,而不是暴力。在写代码之前就说出剪枝规则(“当前缀无法延伸成任何单词时就跳过”)以及由此得到的复杂度——这把一个 hire 和一个枚举全部 2ⁿ 然后超时的候选人区分开来。
何时往前走: 写代码前你能说出剪枝规则和复杂度,并且 212 能在 ≤40 分钟内完成。
下一段 → 212 之所以能做,只是因为你按规格构建了一个 Trie——insert、search、prefix。 按 API 设计一个数据结构、让每个操作都达到目标复杂度,就是最后一段。
Stage 10 · 对象设计(收尾)
类别: Object Design。依赖: 全部——stage 0 的 linked list、stage 3 的 stack、 stage 6 的 heap、stage 9 的 Trie。
你拿到一份 API 规格,被要求实现这个类。工作在于挑选后端结构并保持它们的不变式同步。Meta 和 Amazon 很依赖这类;Google 用它们作为追问的脚手架。对资深后端候选人,它们还考察 API 设计和 可扩展性。
- 155. Min Stack — 五分钟的设计热身:一个保持 同步的辅助 stack。
- 146. LRU Cache — 经典的”30 分钟内设计 + 编码”,到处都考。Doubly-linked list + HashMap;从白纸开始把它写干净。
- 380. Insert Delete GetRandom O(1) — HashMap + 数组与末尾交换。允许重复的变体 381 是合理的资深追问。
- 295. Find Median from Data Stream — 来自 stage 6 的两个 heap。任何”在流上做在线聚合”都归约为两个 heap 或一个有序结构。
- 208. Implement Trie (Prefix Tree) — 你在 212 里依赖的那个结构,现在按规格把它造出来。从零开始 10 分钟以内。
- 355. Design Twitter — 对象建模、heap merge(stage 6 的 23)和 API 设计合于一题。资深后端的最爱:考察你是整体地 设计,还是去 hack 测试用例。
Caution
常见错误: 为了通过给定的测试去 hack 各个操作,而不是选择能让每一个操作都达到目标复杂度的后端结构。LRU 不是”一个带淘汰的 hash map”——它是一个 hash map 加上一个 doubly linked list,并且两者保持同步。把这个不变式说出来。
何时往前走: LRU Cache 从白纸开始 ≤20 分钟完成,并且每个设计你都能说出把各个结构绑在 一起的那个不变式。
下一段 → 路径走完了。Stage 11 用全难度来检验它,每个前面的阶段各一道 hard。
Stage 11 · 每段一道 hard 复练
不是新技术——而是每一段的 hard 版本,这样一旦失手,就能直接定位回需要重做的那一段。
| 题目 | 复测阶段 | 为什么在这里 |
|---|---|---|
| 25. Reverse Nodes in k-Group | 0 | stage 0 的反转,分段进行,一个指针都不能丢 |
| 239. Sliding Window Maximum | 1 + 3 | 一个状态是 monotonic deque 的 window |
| 41. First Missing Positive | 2 | hash map 状态存在数组本身里,O(1) 空间 |
| 224. Basic Calculator | 3 | 在解析的压力下维护一个待处理上下文的 stack |
| 297. Serialize and Deserialize Binary Tree | 4 | 层序输出,再按同样顺序读回 |
| 127. Word Ladder | 5 | 在一个你得自己构建的隐式图上做 BFS |
| 269. Alien Dictionary | 5 | 拓扑排序,难点在于把边提取出来 |
| 4. Median of Two Sorted Arrays | 7 | 在划分上二分,而不是在值上 |
| 410. Split Array Largest Sum | 7 | 在答案空间上二分 |
| 72. Edit Distance | 8 | 至今仍有规律出现的 2D 字符串 DP |
| 10. Regular Expression Matching | 8 | 转移分多种情况的 2D DP |
| 460. LFU Cache | 10 | LRU 的不变式,再深一层 |
完成标准: 按目标公司的面试形态,两场冷启动 mock 都在时间内通过。在那之后,也只有在 那之后,再去消化接下来那一层。
问题识别框架
路径是你学习的方式。这是你在白纸前、还没选算法的那一分钟里,路由一道从未见过的题的方式。 它与系统设计 pattern 框架 如出一辙:先识别 pattern,再选择设计。在这里则是:先识别问题类型,再选择算法。
“array、dfs、two-pointer”这样的标签描述的是你已经拿到解法之后的那个解;在你还不知道 面对的是哪种问题时,它们帮不上忙。识别问句可以,因为每一个都只凭题目描述就能回答。
Important
核心要点: 稀缺的技能不是会算法——而是能在一道从未见过的题上识别出类别。背 300 个解法建立不了这种能力;走完上面这条每一段都标明类别的路径,才行。
按这个顺序运行这些问句,取第一个命中的。具体、高精度的问句排在前面,这样一个宽泛的 类别就抢不走本该属于更精确类别的题:
| 提问顺序 | 类别 | 识别问句 | 在哪一段学 |
|---|---|---|---|
| 1 | Object Design | 我是在实现一个带状态和约束的 API 吗? | 10(预演:stage 3 的 901) |
| 2 | Enumeration | 我必须生成所有合法的可能性,或者数出它们吗? | 9 |
| 3 | Traversal | 有没有一个显式或隐式的图、树或网格要去探索? | 4、5 |
| 4 | Ordering | 正确性是否依赖于按从小到大、按优先级或按端点的顺序处理? | 6 |
| 5 | Transformation | 我是在重塑或编码一个已有结构吗——指针、原地重写、字符串算术? | 0、7 |
| 6 | State Maintenance | 在排除了以上所有之后,一次线性扫描配一个小的演进状态能做出来吗? | 1、2、3 |
| 7 | Decision / Optimization | 这是一连串选择、而每个选择都会影响之后的可能性吗? | 8 |
| 8 | Search | 我能在一个有序的答案空间里搜索,而不是去构造答案吗? | 7 |
flowchart LR
Root([识别问题]) --> D1[1 · Object Design]:::design
Root --> D2[2 · Enumeration]:::enum
Root --> D3[3 · Traversal]:::traversal
Root --> D4[4 · Ordering]:::ordering
Root --> D5[5 · Transformation]:::transform
Root --> D6[6 · State Maintenance]:::state
Root --> D7[7 · Decision / Optimization]:::decision
Root --> D8[8 · Search]:::search
classDef design fill:#f3ecfb,stroke:#8250df,stroke-width:2px,color:#1f2937;
classDef enum fill:#eafaf0,stroke:#1a7f37,stroke-width:2px,color:#1f2937;
classDef traversal fill:#e8f1fd,stroke:#0969da,stroke-width:2px,color:#1f2937;
classDef ordering fill:#e6f6f4,stroke:#0e7490,stroke-width:2px,color:#1f2937;
classDef transform fill:#fdeef6,stroke:#bf3989,stroke-width:2px,color:#1f2937;
classDef state fill:#fdf0e6,stroke:#9a6700,stroke-width:2px,color:#1f2937;
classDef decision fill:#fdeaea,stroke:#cf4b2e,stroke-width:2px,color:#1f2937;
classDef search fill:#eef2f1,stroke:#2c5f5d,stroke-width:2px,color:#1f2937;
Note
为什么提问顺序几乎是路径的倒序: State Maintenance 最先学,因为它是基石;但最后才问,因为它的问句(“一次扫描配一点状态?“)对极大比例的题都成立。太早问它,它就会吞掉那些其实是遍历或 DP 的题。按基石优先去学;按精确优先去识别。
这八类覆盖了主流大厂面试中反复出现的推理模式。位运算和纯数学刻意没有成为类别——它们考的 是狭窄的技巧,而不是可迁移的识别,放在下面的低频层里。
接下来:最后的 20%(更多投入,更少收益,但仍真实)
这里没有一样是无用的——它是收益递减的那一层。下面每一组确实会在面试里出现, 只是罕见到相对核心清单是笔糟糕的交易。只有在核心题能在计时下跑顺之后才做这些, 并自上而下地排优先级:靠前的组比靠后的组更能挣回它们的边际投入。
- Hard DP。 312. Burst Balloons、 44. Wildcard Matching、 188. Stock IV 这些变体。在以下情况下试试: stage 11 的 Edit Distance 和 Regex Matching 已经写干净、还有富余时间,或者你的目标是一个喜欢把 DP 变异成更难版本的 Google 面试。Wildcard Matching 是 stage 11 的 Regex Matching 最近的姊妹题—— 从它开始。
- 高级图算法。 743. Dijkstra (Network Delay Time)、 Bellman-Ford、Kruskal/Prim MST。在以下情况下试试: 你的目标是一个 基础设施、地图或物流团队,或专门是 Google 面试——它们只在那里挣得 一席之地,别处几乎没有。从 Network Delay Time 的 Dijkstra 开始; 它是真正会出现的那一个。
- 高级 union-find。 你已经在核心清单上有了经典的 323。 接下来试试: 721. Accounts Merge 和 305. Number of Islands II — 那些真正会出现的应用变体(Meta 喜欢 Accounts Merge)。 跳过带权/带秩路径压缩的竞赛级那一层。
- 位运算。 136. Single Number 是个不错的热身。若目标 Google,接下来试试: 201. Bitwise AND of Numbers Range 和 190. Reverse Bits — Google 偶尔考,别处近乎没有。过一遍用于识别即可。
- 数学 / 实现。 12. Integer to Roman、 13. Roman to Integer、 171. Excel Column Number。 这些考的是仔细的实现,而非模式迁移。低优先级, 但如果考前那周你有个闲下来的晚上,是一次快速的信心过检。
- Hard backtracking。 51. N-Queens、 37. Sudoku Solver、 425. Word Squares。在以下 情况下试试: Subsets 和 Permutations 已经自动化,你想压力测试你的剪枝。 N-Queens 是面试官偶尔会拿出来的那一道。
- Segment / Fenwick tree。 307. Range Sum Query - Mutable、 315. Count of Smaller Numbers After Self。 大多属于竞赛编程领域。只在以下情况下试试: 你的目标是一个已知会问它们的 quant/HFT 或专家级基础设施面试——否则那个边际投入的一小时,花在系统设计上 要好得多。
- 完整的 Blind 75 / NeetCode 250,为了完整性。 不错的模式目录, 在核心处与本清单大量重叠——如果你做了其中一个,你就打好了基础。把全部 250 道当作目标来完成,是在用题量优化,而非模式熟练度。如果你确有富余 时间,挑几道它们覆盖而本清单没有的;别死磕整套。
- 超过几场的 mock 面试平台。 两三场对校准是值得的。此后,边际价值 急剧下降;真实的计时实战胜过被观看的。
这一层背后的规律:主流大厂面试考的是广度和速度,而非任何单一技术的深度。 这些题真实但罕见——所以上面的排序是刻意的。只有在核心清单已经流畅之后,才自上而下 花费下去,并在那个边际投入的一小时买到的系统设计价值超过再多学一门冷门技术时停下。
各公司侧重
- Meta — 每 35 分钟一轮两道题;速度是全部的游戏。在数组/字符串和树上 过度投入;预期上面标记的 Meta 最爱(Valid Palindrome II、 Vertical Order Traversal、Minimum Remove、Find All Anagrams)。
- Google — 一道会变异的题:在你解完之后,约束会变(“如果放不进内存怎么办?”、 “如果更新是并发到达的怎么办?”)。练习扩展你自己的解法;toposort 和 search-on-answer 的 binary search 在这里比别处出现得更多。
- Amazon — 同一小时内一道题加上 leadership-principle 问题,对可维护性的 打分和正确性一样重——见 logical & maintainable 指南。 BFS-on-grid、k-way-merge 和 monotonic stack 是招牌常客。
- Apple / Netflix — 团队驱动且务实;上面的 Object Design 类别是收益最高的 一组,而语言熟练度算双倍分。
各公司 Priority 10
如果你对每个目标公司只有做 10 道题的时间,这些是上面清单里 ROI 最高的选择:
资深候选人的不同之处
同一道题,由一个中级和一个资深候选人解出来,在面试官的记录里看起来不一样:
| 动作 | 中级 | 资深 |
|---|---|---|
| 开场先…… | 直接跳到写代码 | 澄清那些会改变思路的假设 |
| 思路 | 陈述一个解法 | 讨论 2 个备选方案,带理由选一个 |
| 实现 | 写出正确的代码 | 写出正确的代码,配好命名和结构 |
| 测试 | 走一遍 happy path | 测 happy path + 说出抓到的失败模式 |
| 复杂度 | 提到 Big-O | 解释什么会改进它、以及你什么时候会在意 |
| 边界情况 | 被提示时处理 | 主动处理并说出它们 |
| 追问 | 从头再来 | 用追问阶梯适配已有解法 |
规律:在资深级别,每一个标准动作都附带一句额外的元推理。见 coding round 指南的资深区分一节 了解如何练习这一点。
如何使用这份清单
按顺序走完各个阶段,在该阶段的何时往前走标准成立之前不要前进。卡在一道题上时,往回退 一段,而不是往前冲——每一段都写明了它依赖什么,跳过某个前置几乎总是一道题让你觉得做不出来的原因。
如果你有 6 周(60–80 小时):
| 周 | 阶段 | 重点 |
|---|---|---|
| 1 | 0、1 | 第一天刷完热身,然后是 window 链 |
| 2 | 2、3 | 前缀状态和 monotonic stack——基石到此完成 |
| 3 | 4、5 | 先树,后图 |
| 4 | 6、7 | 有序处理和搜索 |
| 5 | 8、9、10 | DP、回溯、对象设计 |
| 6 | 11 + 重做 | hard 复练,重做每一道没达到时间的题,两场计时 mock |
如果你有 2 周(20–25 小时):stage 0–6,加上 stage 10 的 LRU Cache 和 Insert/Delete/GetRandom,约 35 题。DP 做到 House Robber 为止,回溯做到 Subsets 为止—— 目标是在最高频的阶段上提速,而不是求全。
如果你只有 3 天:stage 0(半个上午)、stage 1–2、stage 4–5 中的五道(543、236、102、 200、994),以及 stage 10 的两道(146、380)。你是在刷新速度,不是在准备一整场面试。 不要碰”接下来”那一层。
会员 dashboard 里的自学面试准备项目,用的就是这些阶段、这个顺序,作为它的 coding 部分—— stage 2 的 560 跟滑动窗口一起放在第 2 周,stage 2 其余的题和 stage 3 共用第 3 周,stage 11 占两周。
对所有时间线:给自己计时。18 分钟解出一道题和用 38 分钟解出同一道题之间的差别, 就是本清单上每一家公司的 hire 和 no-hire 之间的差别。不计时的练习教的是错误的技能。
相关
- 指南:大厂资深 coding 面试 — 如何把控时间:各公司的面试形态、6 步结构、追问阶梯,以及那些读起来资深的动作。
- 指南:Amazon 的 Logical & Maintainable coding 面试 — 那个把干净、可扩展的代码作为明确评分标准的公司专门化。
- 计划:资深后端软件工程师面试准备 — 更宏观的 12 周计划,覆盖 coding、系统设计和行为面试。
- 框架:系统设计中的 Pattern 与权衡 — 系统设计这一侧的对应物:先识别路径 pattern,再选择设计。