大多数”公司 X 的 LeetCode”清单都是从聚合站抓来的 250 道题,没有任何注释, 留给你自己去猜哪 30 道才真正承载信号。这份清单反其道而行。它是约 60 道核心题, 按一个问题识别框架组织——八种可识别的问题类别,每一类都配有一个你可以在 还没选算法之前就问自己的问句——外加一个由经久不衰的老经典组成的热身层, 以及一个分级的”接下来”层,用于在核心题目能在计时下跑顺之后,去争取最后 20% 的价值。
校准假设:你的目标是中到资深级别的面试(Meta E4/E5、Google L4/L5、 Amazon SDE II/III,或同等级别)。模式覆盖延伸到资深难度;应届生面试考的是 同样模式的更简单切片。搭配 coding round 指南 一起看,了解进了考场之后如何把控时间。
为什么标签清单效率低下
打开任何一个”公司 X 的 LeetCode”页面,你会看到 20 多个标签——array、 string、tree、dfs、bfs、two-pointer、recursion、backtracking、greedy、heap, 等等。标签描述的是你已经拿到解法之后的那个解。它们对决定整场面试的那一刻 毫无帮助:那张白纸前的一分钟——此时你还不知道自己面对的是哪种问题。一个”背熟了标签” 的候选人照样可能卡住,因为在你想出思路之前,标签根本不可见。
识别比记忆更重要
那些通过面试的资深候选人,不是背下了 300 个解法的人。他们是那些面对一道陌生题时, 能迅速识别这是哪一类问题的人——思路会从识别中自然推导出来。这与 系统设计权衡框架 如出一辙:先识别权衡,再选择方案。在这里则是:先识别问题类型,再选择算法。
这重新定义了这份清单的用途。下面这约 60 道题不是一张要逐项打勾完成的清单—— 它们是一套识别程序的训练数据。把每个类别内化一道题,你就能路由一道从未见过的题。
从这里开始
| 如果你需要…… | 去看 |
|---|---|
| 用来练习的题目(你在这里) | 本清单 |
| 如何把控整场面试 | 指南:大厂资深 coding 面试 |
| Amazon 特有的 coding 标准 | 指南:Amazon 的 Logical & Maintainable |
| 完整的 12 周计划 | 计划:资深后端面试准备 |
问题识别框架
先识别,后实现。 在选算法之前,先识别你要解的是哪一类问题。几乎每一道 主流大厂题都能回答下面某一个识别问句——每个问句都在你选定数据结构之前被提出。 关键技能是按顺序运行这些问句,直到有一个命中;命中的类别随即告诉你该用什么技术。
Important
核心要点: 稀缺的技能不是会算法——而是能在一道从未见过的题上识别出类别。背 300 个解法建立不了这种能力;把每个类别内化一道题、能在毫无准备时识别出来,才行。先识别,后实现。
| # | 类别 | 识别问句 | 典型技术 |
|---|---|---|---|
| 1 | Object Design(对象设计) | 我是不是在实现一个带状态和约束的 API? | hash map + linked list、dual heaps |
| 2 | Enumeration(枚举) | 我是不是必须生成所有合法可能? | backtracking、recursion |
| 3 | Traversal(遍历) | 我是不是在探索一个 graph、tree 或 grid? | DFS、BFS、union-find |
| 4 | Ordering(有序处理) | 解法是否依赖于按顺序处理事物? | sort、heap、merge、interval、sweep line |
| 5 | Transformation(变换) | 我是不是在变换或编码一个已有的结构? | linked list、string manipulation、array rewrite、encode/decode |
| 6 | State Maintenance(状态维护) | 在排除以上所有之后——一次线性扫描配一个小的演进状态能不能搞定? | hash map、prefix sum、sliding window、two pointers、monotonic stack |
| 7 | Decision / Optimization(决策/优化) | 我是不是在做一连串选择,其中每个选择都影响后续的可能性? | dynamic programming、greedy |
| 8 | Search(搜索) | 我能不能搜索一个有序的答案空间,而不是去构造答案? | binary search、search-on-answer |
识别顺序
顺序很重要。按顺序运行这八个识别问句,取第一个吻合的类别。先问具体、 高精度的问句,让宽泛的那些落到后面——否则一个宽泛类别会抢走本该由更锐利的 类别拥有的题:
flowchart LR
Root([识别问题类型]) --> D1[1 · 对象设计]:::design
Root --> D2[2 · 枚举]:::enum
Root --> D3[3 · 遍历]:::traversal
Root --> D4[4 · 有序处理]:::ordering
Root --> D5[5 · 变换]:::transform
Root --> D6[6 · 状态维护]:::state
Root --> D7[7 · 决策/优化]:::decision
Root --> D8[8 · 搜索]:::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;
每个叶子是一个类别;数字是它在问句顺序中的位置——先问第 1 个问句,在第一个 吻合的类别停下。每个类别的识别问句和技术见下面的八大类别一节。 State Maintenance(6)是兜底类别——只有在排除了更具体的 1–5 之后才落到这里。
Note
为什么状态维护排在最后: 它的问句(“一次线性扫描配一点状态?“)对极大一部分题目都成立,所以太早问它 会让它吞掉那些其实是 traversal 或 DP 的题。它被刻意放在最后几个识别问句里—— 只有在排除了上面更具体的模式之后才用它。
八大类别
下面每个类别都用同一种结构——要问自己的识别问句、它解锁的典型技术, 以及教会你这一类的代表题(链接在清单里)。
Object Design(对象设计)
- 问自己: 我是不是在实现一个带状态和约束的 API/对象——“用这些操作、在这些复杂度下构建一个类”?
- 典型技术: hash map + doubly linked list、dual heaps、保持同步的辅助结构。
- 代表题: LRU Cache · Insert Delete GetRandom · Find Median from Data Stream · Min Stack · Design Twitter · Implement Trie。
Enumeration(枚举)
- 问自己: 我是不是必须生成所有合法配置(或数出它们的个数)——每一个 subset / permutation / combination / 合法字符串?
- 典型技术: 带剪枝的 backtracking、recursion tree。
- 代表题: Subsets · Permutations · Letter Combinations · Word Search II。
Traversal(遍历)
- 问自己: 有没有一个显式或隐式的 graph、tree 或 grid 要探索?克隆和序列化一个结构也属于这里——工作在于遍历,而非编码。
- 典型技术: DFS、BFS、multi-source BFS、topological sort、union-find。
- 代表题: Number of Islands · LCA · Binary Tree Max Path Sum · Level Order · Course Schedule · Rotting Oranges · Clone Graph · Connected Components。
Ordering(有序处理)
- 问自己: 正确性是否依赖于一个全局顺序——我是不是必须先处理最小的、按优先级处理,或按端点扫描区间?
- 典型技术: sort、heap、k-way merge、interval sweep、sweep line。
- 代表题: Merge Intervals · K Closest Points · Kth Largest · Merge k Sorted Lists · Meeting Rooms II。
Transformation(变换)
- 问自己: 核心任务是不是重塑或编码一个已有结构——重接 linked-list 指针、原地重写一个数组、解析/编码一个字符串?(Trie 是你在这里可能用到的一种技术,不是一个类别。)
- 典型技术: 指针/下标操作、原地重写、encode/decode。
- 代表题: Add Strings · 热身层里的 linked-list 经典题(Reverse、Merge Two、Cycle)。
State Maintenance(状态维护)
- 问自己: 一次线性扫描配一个小的演进状态能不能搞定——在排除以上所有之后?这是兜底类别,被刻意放在树的靠后位置。
- 典型技术: hash map、prefix sum、sliding window、two pointers、monotonic stack。
- 代表题: Longest Substring Without Repeat · Group Anagrams · Product Except Self · Best Time to Buy/Sell · Daily Temperatures · Minimum Window Substring · Subarray Sum Equals K。
Decision / Optimization(决策/优化)
- 问自己: 我是不是在做一连串选择,其中每个选择都影响后续的可能性,并在整体上优化一个 min/max/count?(DP 和 greedy 都落在这里。)
- 典型技术: dynamic programming;当一个局部规则可被证明最优时用 greedy。
- 代表题: Climbing Stairs · Coin Change · Word Break · Unique Paths · House Robber。
Search(搜索)
- 问自己: 我能不能搜索一个有序的答案空间,而不是去构造答案——一个有序数组,或一个我可以二分的单调答案空间?(这比”在有序数组里做 binary search”更宽泛:rotated-array search 和 search-on-answer 都属于这里,因为二者都在对一个有序空间做 binary search。)
- 典型技术: binary search、binary-search-on-answer。
- 代表题: Search in Rotated Sorted Array · Random Pick with Weight · Pow(x, n)。
Tip
本框架的范围: 这八类涵盖了主流大厂面试中反复出现的推理模式。位运算和纯数学被有意排除在一等类别之外——它们属于一个独立的低频层(见接下来)。这是刻意的设计选择,不是漏掉的类别:它们考的是冷知识和狭窄的技巧,而非可迁移的识别能力。
清单
下面每一道题都由识别框架安放——它是某个类别的一个例子,而不是一个独立条目。 不要背这份清单。对每一道题,先练习识别它属于哪个类别(跑一遍那棵树),然后 解那个类别里的代表题,直到识别变成自动的。那种迁移——先类别,后解法——才是全部 的重点;这些题只是训练数据。
分组遵循识别顺序。那是你问问句的顺序——不一定是你练习的顺序(见 如何使用这份清单里从基石开始的次序)。一个由老经典组成的 简短热身层收尾整份清单。
1. Object Design(对象设计)
你拿到一份 API 规格,被要求实现这个类。工作在于挑选后端结构并保持它们的不变式 同步。Meta 和 Amazon 很依赖这类;Google 用它们作为后续追问的脚手架。对资深后端 候选人,它们越来越考察生产直觉:API 设计、对象建模、可扩展性和权衡推理。
- 146. LRU Cache — 那道 经典的”30 分钟内设计 + 编码”,到处都在考。Doubly-linked list + HashMap。 在白板上把它写干净,这个模式就内化了。
- 380. Insert Delete GetRandom O(1) — HashMap + 动态数组交换。允许重复的变体 381 是一个合理的资深追问。
- 295. Find Median from Data Stream — 两个 heap。模式比题目本身更重要:任何”在流上做在线聚合”都归约为 两个 heap 或一个有序结构。
- 155. Min Stack — 五分钟的 设计热身;辅助结构的思路会在更难的设计里再次出现。
- 355. Design Twitter — 在一道题里综合了对象建模、heap merge 和 API 设计。资深后端的最爱: 考察你是整体地思考设计,还是只是去 hack 测试用例。练那个干净的 OO 版本。
- 208. Implement Trie (Prefix Tree) — 按规格实现一个类(insert、search、startsWith)。Trie 是那个 技术;这里的识别是”按 API 构建这个数据结构”。如果你无法在 10 分钟内 从零写出来,就练到能为止。
Caution
常见错误: 去 hack 那些操作以通过给定的测试,而不是选择让每个操作都命中其目标复杂度的后端结构。LRU 不是”一个带淘汰的 hash map”——它是一个 hash map 加一个 doubly linked list,保持同步。把不变式大声说出来。
2. Enumeration(枚举)
答案是每一个合法配置(或其个数)。识别线索是”生成所有……”→ 带剪枝的 backtracking。把模板过一遍;资深标准的变体是带重复的排列,而不是什么奇异谜题。
- 78. Subsets — 那道经典 模板。用 include/exclude 递归和 5 行的位运算版本各写一遍——后者是那种 面试官会记住的东西。
- 46. Permutations — 原地 swap 的版本最干净;带重复的变体 47 是常见的追问。
- 17. Letter Combinations of a Phone Number — 最友好的 backtracking 题,也是常见的热身;这个模板可迁移到每一个 “枚举组合”的追问。
- 212. Word Search II — 在 grid 上做 backtracking,用 Trie 剪枝。资深面试层级。识别是 “枚举路径”;Trie 是让它可行的技术。
Note
面试信号: 枚举题上的资深动作是剪枝,不是暴力。在你写代码之前就说出剪枝规则(“当前缀无法扩展成任何单词时跳过”)——以及由此得到的复杂度——这才是把 hire 和一个枚举全部 2ⁿ 并超时的候选人区分开来的东西。
3. Traversal(遍历,第二轮)
有一个 graph、tree 或 grid 要探索。第二轮 coding 通常从这里出题。标准变了: 不再是”12 分钟内写干净”,而是”25 分钟内正确,并对权衡有一段合理的讨论”。克隆和 序列化一个结构也属于这里——工作在于遍历,而非编码。
- 200. Number of Islands — 经典的 grid 遍历,到处不停地考。用 DFS 和 BFS 模板各解一遍, 你就覆盖了大部分 grid 题。
- 236. Lowest Common Ancestor of a Binary Tree — 经典的递归分治。变体(带 parent 指针的 LCA)是常见追问。
- 124. Binary Tree Maximum Path Sum — 后序遍历配全局最大值跟踪。那个”向上返回一个值、在全局记账另一个值”的 模式,是 tree recursion 的资深版本。在 Google 和 Meta 高频。
- 543. Diameter of Binary Tree — 同一个”返回 + 记账”模式的更简单版本。如果 124 觉得难,从这里开始。
- 199. Binary Tree Right Side View — level-order BFS 或 preorder DFS。两个都练——面试官在你给出第一个解法后 常会要求另一种。
- 102. Binary Tree Level Order Traversal — tree 的 BFS 模板。很多 tree 题都归约为”带记账的 level-order”——这是 基础模板。它也是树序列化的骨架(BFS/DFS 出去,按同样顺序还原回来)—— 一个常见追问。
- 314. Binary Tree Vertical Order Traversal — 那道 Meta 的 tree 题;别处也出现。带列跟踪的 BFS。有名到面试官能分辨 出背的和推理出来的——要能第一次就干净地写出来。
- 207. Course Schedule — 环检测 / topological sort,Google 和 Amazon 的常客。要会 Kahn 算法 (BFS 入度);追问 210. Course Schedule II 要的是排序本身。
- 994. Rotting Oranges — multi-source BFS,Amazon 的最爱。“从所有源同时开始 BFS”这个洞察 可迁移到许多 grid 上的最短时间问题。
- 133. Clone Graph — 带一个 HashMap(映射 原图→副本)的图遍历。识别是遍历(DFS/BFS 遍历这个图); 克隆是过程中的记账。陷阱:把递归与迭代的权衡说错。
- 323. Number of Connected Components in an Undirected Graph — 用 BFS/DFS 或 union-find 都能解。练那个 union-find 版本—— 15 分钟就能学会,而这个模式在 Google、Meta 和 Databricks 出现的 频率高得惊人。
Tip
为什么 BFS vs DFS 是一个真实的选择: 对可达性和连通分量,默认用 DFS(代码更短);一旦题目暗示距离或层级——无权 grid 上的最短路径、“所有橘子腐烂需要几分钟”、level-order 输出——立刻切换到 BFS。说出你为什么选其中之一才是信号;凭习惯选则不是。
4. Ordering(有序处理)
正确性依赖于按特定顺序看到元素——先排序、从 heap 里取、或按端点扫描区间。如果 “处理最小的 / 下一个”是关键动作,那就是 Ordering。强候选人在这里靠正确的数据 结构选择让自己脱颖而出。
- 56. Merge Intervals — 经典的区间题,每家公司都高频。Sort + 线性 merge。 57. Insert Interval 和 435. Non-overlapping Intervals 的模板都从这道题里推导出来。
- 973. K Closest Points to Origin — 经典的 top-k。用一个 size-k heap 和 quickselect 各解一遍, 并解释你什么时候选哪个——那个流式数据的追问其实是在问你为什么选了 heap。
- 215. Kth Largest Element in an Array — 同样的模式,更简单的表述。Quickselect 是经典答案; 解释 average-O(n)/worst-O(n²) 的权衡就是那个信号。追问总是 “你怎么避免 O(n²)?“——随机化 pivot 选择。主动说出来。
- 23. Merge k Sorted Lists — heap-of-heads,Amazon 和 Google 的常客。k-way-merge 模板 也是追问里外部排序讨论的底层基础。
- 253. Meeting Rooms II — 在结束时间上的 min-heap。诀窍在于识别出”哪个最小的结束时间是空闲的” → heap。常见变体:数出并发会议数。
Note
面试信号: 对 top-k,写出那个 size-k heap 并说出 quickselect——然后说你什么时候选哪个:流式数据或 k ≪ n 时选 heap,一次性的内存数组选 quickselect。对 quickselect,在被问之前就主动交代 O(n²) 最坏情况和随机化 pivot 的修复。当一个 heap 就够时却上完整排序,读起来很 junior。
5. Transformation(变换)
主要挑战是重塑或编码一个已有结构:重接 linked-list 指针、原地重写数组、解析或 编码字符串。经典的热身是最后一节里的 linked-list 经典题;在核心集里,典范是 字符串进位算术。
- 415. Add Strings — 手写
进位算术(不用
BigInteger)。常作为热身;一个常见追问是 43. Multiply Strings。 识别:你在变换/编码,而不是搜索或优化。
Caution
常见错误:
在 linked-list 变换上,因为在保存 next 之前就重接了它而丢了一个节点。把指针画出来,用一个 dummy head,并按正确的顺序前进。这些看起来微不足道,但在一道”简单”的热身上丢一个指针或差一个 off-by-one 就是即时的 no-hire。
6. State Maintenance(状态维护——基石,练到不假思索)
兜底类别:一次线性扫描的同时维护一个小的演进状态——一个 running count、一个 window、一个 monotonic stack。只有在上面全都没命中时才用它。大多数面试的第一道 coding 题从这里出。12–15 分钟内用干净代码解出来是标准;25 分钟很可能挂掉这一轮, 即使解法能跑。
- 3. Longest Substring Without Repeating Characters — 经典的 sliding window,到处都考。如果你无法在 8 分钟内写出这道题的 two-pointer 模板,清单里其余的题帮不了你。先做这道。它也是下面 sliding window 依赖链的入口。
- 49. Group Anagrams — 用派生 key(排序后的字符串或字符计数)的 hash map。考察你能否为 基于 hash 的分组设计出正确的 key——这个模式可迁移到许多”按属性分组”的题。
- 238. Product of Array Except Self — 不用除法的 prefix/suffix product。那个”在两个方向上维护状态”的 模式有许多变体出现;这是最干净的。
- 121. Best Time to Buy and Sell Stock — 单遍历跟踪最小值。全部重点:候选人会过度设计。好的解法是 10 行。
- 125. Valid Palindrome — two-pointer 字符串热身,常与 680. Valid Palindrome II 作为追问配对(一道 Meta 最爱)——两个都准备。
- 42. Trapping Rain Water — Amazon 和 Google 在资深标准上的常客。带 running max 的 two-pointer; 也可以用 monotonic stack 解。知道两种并说出权衡就是资深信号。
- 1249. Minimum Remove to Make Valid Parentheses — 高频,尤其在 Meta。两遍扫描或 stack。常与 301. Remove Invalid Parentheses 作为资深级追问配对。
- 739. Daily Temperatures — 经典的 monotonic stack 题。“对每一天,还要几天才有更暖的一天?” 维护一个有序的 stack,让你在 O(n) 内回答”next greater”。在 Amazon 高频。
- 84. Largest Rectangle in Histogram — 更难的经典 monotonic-stack。理解 stack 为什么在这里能行,也就解锁了 Trapping Rain Water 的 stack 解法。
- 76. Minimum Window Substring — 更难的经典 sliding window。任何”包含 X 全部的最小窗口”问题的模板。
- 560. Subarray Sum Equals K — prefix sum + HashMap。那个经典的”这其实不是 sliding window” 陷阱:先去够 window,负数就会把你破掉。学会识别它。
- 438. Find All Anagrams in a String — 带频率计数的定长 window。在 Meta 高频。带字符计数的 “维护一个合法 window”模式。
Caution
常见错误: 在不变式不成立时硬套 sliding window。Subarray Sum Equals K 看起来像一个 window,但负数破坏了单调性——它是 prefix-sum + hash map。当一个 window 需要不可预测地既增长又收缩时,那就是它不是 window 的信号。
7. Decision / Optimization(决策/优化——比互联网所暗示的更小的一片)
每一步都是一个选择,其价值取决于更早的选择,而你在优化整个序列上的一个 min/max/count:dynamic programming,或当局部规则可被证明最优时用 greedy。 每家公司都考某种 DP;主流面试没有一家考最难的那一层。宽泛地覆盖模式,而不是 死磕 30 道特定题——下面每个模式一道题就覆盖了大部分出现的情况。
- 70. Climbing Stairs — 热身;带两状态记忆的 1D DP。琐碎,但更复杂的 1D DP 的框架。
- 322. Coin Change — 经典 unbounded knapsack。内化那个自底向上的表;迭代式是你在计时下会写的。
- 139. Word Break — 带 hashset 查找的字符串 DP。变体 140. Word Break II (DP + backtracking)只在资深标准上才值得练。
- 62. Unique Paths — 那个 2D grid 计数模板;带障碍的变体 63 随之推导出来。
- 198. House Robber — 最 干净的 take/skip 决策 DP;环形变体 213 是一个合理的追问。
Tip
为什么从递推式开始,而不是从表开始: 任何 DP 的难点都是命名状态和转移——“dp[i] 是什么意思,它如何从更早的条目构建起来?“在写代码之前把那句话大声说出来。表(1-D vs 2-D、top-down vs bottom-up)在递推式正确后自然落定;先跳到数组是候选人卡住的原因。
8. Search(搜索)
答案存在于一个有序空间里,或一个你可以二分的单调答案空间里,而不是一个你必须 构造的空间。放在最后问,因为”搜索答案”会与 DP 表述竞争——先排除其他的。别跳过它: 它是最容易因一个 typo 而失败的模式,也是最干净、值得背下来的模板。
- 33. Search in Rotated Sorted Array — 经典的”带转折的 binary search”,到处都考。15 分钟内零 off-by-one 写出来, 这个模式就覆盖了。带重复的变体 81 是常见追问。
- 528. Random Pick with Weight — cumulative 数组 + binary search;在 Meta 高频。setup 阶段 是问题的一半。
- 50. Pow(x, n) — 递归的 二分幂。容易出 bug;练那个 negative-n 边界情况。
Caution
常见错误:
因边界约定不一致而导致的 off-by-one 和死循环。挑一种——[lo, hi] 闭区间或 [lo, hi) 半开——并在整个解法里保持一致。大多数”binary search 很简单”的失败,都是一个 < vs <=,或一个与约定不匹配的 mid ± 1。
Old classics(老经典——热身层,仍在被考)
附录,不是一个类别:CtCI 时代的热身题,至今仍开启电话面试。那些 linked-list 的 兼作经典的 Transformation 练习(指针重接)。别死磕它们——只要确保没有一道 能让你措手不及。
- 206. Reverse Linked List — 史上最常被考的热身。迭代和递归,两个都在五分钟内。半数 linked-list 追问背后的基础技术。
- 21. Merge Two Sorted Lists — 那个 two-pointer merge,23. Merge k Sorted Lists (在 Ordering 里)是它的推广。先把这道烂熟于心。
- 141. Linked List Cycle — Floyd 的快慢指针。追问 142(找环的 起点)才是资深标准上真正会被考的版本。
- 20. Valid Parentheses — 经典的 stack 热身;是 State Maintenance 里 1249. Minimum Remove 的前置。
- 1. Two Sum — 人人都见过的 hash-map 一行解。仍是一个真实的电话面试开场;重点是在 90 秒内解出来 并继续,而不是被打个措手不及。
- 88. Merge Sorted Array — 从后往前的原地 merge。一个出人意料常见的 Meta/Amazon 热身, “从末尾开始填”的技巧就是全部信号。
接下来:最后的 20%(更多投入,更少收益,但仍真实)
这里没有一样是无用的——它是收益递减的那一层。下面每一组确实会在面试里出现, 只是罕见到相对核心清单是笔糟糕的交易。只有在核心题能在计时下跑顺之后才做这些, 并自上而下地排优先级:靠前的组比靠后的组更能挣回它们的边际投入。
- Hard DP。 72. Edit Distance、 312. Burst Balloons、 44. Wildcard Matching、 188. Stock IV 这些变体。在以下情况下试试: 你在 Coin Change、Word Break 和 House Robber 上很扎实、还有富余时间,或者你的目标是一个喜欢把 DP 变异成 更难版本的 Google 面试。Edit Distance 是这里价值最高的一道——它是唯一 一道至今仍以任何规律性出现的。
- 高级图算法。 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 指南的资深区分一节 了解如何练习这一点。
每个类别内部的依赖链
框架告诉你一道题是哪个类别;这些链告诉你在一个类别内部的练习顺序。一旦你 识别出一个类别,就按依赖顺序走它的代表题——每一道都教一个下一道会假定你已会的技术。 识别 → 代表题 → 这条链。
State Maintenance(sliding window 子链): 3 Longest Substring → 567 Permutation in String → 76 Minimum Window Substring → 438 Find All Anagrams
Ordering(interval 子链): 56 Merge Intervals → 57 Insert Interval → 253 Meeting Rooms II → 435 Non-overlapping Intervals
Traversal(tree recursion 子链): 543 Diameter(返回 + 记账) → 124 Maximum Path Sum(同样的模式,更难) → 236 LCA(递归分治)
Traversal(graph 子链): 200 Number of Islands(grid DFS/BFS) → 994 Rotting Oranges(multi-source BFS) → 207 Course Schedule(toposort) → 323 Connected Components(union-find)
Decision / Optimization(DP 子链): 70 Climbing Stairs(1D 基础) → 198 House Robber(take/skip) → 322 Coin Change(unbounded knapsack) → 139 Word Break(string DP)
Object Design(链): 155 Min Stack(辅助结构) → 146 LRU Cache(DLL + HashMap) → 380 Insert Delete GetRandom(array + HashMap swap) → 355 Design Twitter(对象建模 + heap merge)
Search(链): 基础有序数组 → 33 Search in Rotated → 528 Random Pick with Weight(prefix sum + search)
如果一道题感觉不可能,检查一下你是不是在链里跳过了它的前置。往回退一步,几乎总是 比死磕着往前走更快。
如何使用这份清单
从基石开始练习(与识别顺序相反——你先学常见类别,再学罕见的):
- 第 1 周第 1 天:把 老经典 作为热身闪电解一遍——六道题,一次坐下,计时。 它们是地板;在往上搭建之前确认没有一道能让你措手不及。
- 第 1–2 周:State Maintenance + Traversal,按顺序。约 30 道题干净地解出。 标准是”在目标时间内写出干净代码”,而不是”至少做完了”。
- 第 3 周:Ordering + Search(heap、interval、binary search)。
- 第 4 周:Decision/Optimization + Object Design + Enumeration。
- 第 5 周:重解你在第 1–4 周里没能按时完成的一切。是重复实战,不是新题。如果核心 真的流畅了,就从顶部开始花费接下来那一层——Edit Distance、Accounts Merge、 Dijkstra——而不是整套。
- 第 6 周:两场按你目标公司面试形态的计时 mock。根据在压力下崩掉的部分做调整。
如果你有 2 周(20–25 小时):
跳过 House Robber 以外的 Decision/Optimization(DP)。跳过 Subsets 以外的 Enumeration。专注于 State Maintenance、Traversal、Ordering 和 Object Design。 约 25–30 道题。目标不是完整——而是在最高频类别上的模式识别。
如果你有 3 天:
四组:老经典(六道热身,半个上午)、State Maintenance(基石集)、 Traversal(五道 tree/graph 题),以及两道 Object Design 题 (LRU Cache、Insert/Delete/GetRandom)。你不可能在 3 天里备好一场面试;你要做的是 在最可能出现的类别上刷新速度。不要碰”接下来”那一层——在这个时间线上它是纯粹的 收益递减。
对所有时间线:给自己计时。18 分钟解出一道题和用 38 分钟解出同一道题之间的差别, 就是本清单上每一家公司的 hire 和 no-hire 之间的差别。不计时的练习教的是错误的技能。
相关
- 指南:大厂资深 coding 面试 — 如何把控时间:各公司的面试形态、6 步结构、追问阶梯,以及那些读起来资深的动作。
- 指南:Amazon 的 Logical & Maintainable coding 面试 — 那个把干净、可扩展的代码作为明确评分标准的公司专门化。
- 计划:资深后端软件工程师面试准备 — 更宏观的 12 周计划;它的 coding 部分和这份清单从两个方向覆盖同样的模式。