在 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 中保持模式卡組活躍。它已成為我的外部演算法大腦——每當我需要解決對映到經典模式的生產問題時,它總在那裡。

