
1. 先把題單和日歷拆開看75 題分類與 31 天路線圖到底解決什么問題刷題這件事最怕兩件事一是不知道刷什么二是知道刷什么但排不出時間。很多人的狀態(tài)是收藏夾里存了幾十份題單真正動手的那份還是三年前的。劍指 Offer 這套題一共 75 道題目質(zhì)量確實高覆蓋面和面試貼合度都不錯但它有個天然的門檻——題號順序是按“出題順序”排的不是按“學(xué)習(xí)順序”排的。你從第一題順著往下做會在數(shù)組、字符串、鏈表、樹、DP 之間來回橫跳每跳一次都要重新熱身效率很低。所以75 題算法分類的意義不是把題分個類好看而是把“同一套思維模型”的題壓在一起讓你在做第 3 道題的時候第 1 道題的手感還在。而31 天刷題路線圖解決的是另一個維度的問題分類解決“怎么學(xué)”路線圖解決“什么時候?qū)W、學(xué)多少、什么時候回頭”。這兩件事必須一起設(shè)計只分類不排期大概率變成前三天猛刷二十題、后面徹底擺爛只排期不分類就是每天機械打卡做題全憑運氣。我這套方案的適用人群很明確有一點編程基礎(chǔ)能看懂?dāng)?shù)組和鏈表但面對中等難度題容易卡殼或者刷過幾十道題但不成體系面試前想快速把高頻題過一遍。完全零基礎(chǔ)的人也能跟但前兩天會稍微吃力需要額外補一下復(fù)雜度分析和遞歸的基本概念。整篇內(nèi)容我會把每一類題在考什么、路線圖每一天做多少、每道題做到什么程度算過關(guān)全部攤開講你可以直接拿去改日期抄作業(yè)。2. 75 題算法分類的底層依據(jù)按思維模型分組而不是按數(shù)據(jù)結(jié)構(gòu)2.1 為什么“按數(shù)據(jù)結(jié)構(gòu)分類”不夠用大部分人第一次分類會按數(shù)據(jù)結(jié)構(gòu)來數(shù)組一類、鏈表一類、樹一類、圖一類。這個分法直觀但實際用起來會發(fā)現(xiàn)一個問題——同一類數(shù)據(jù)結(jié)構(gòu)里思維方式可能完全不同。比如數(shù)組題里有的是雙指針往中間夾有的是原地覆蓋寫有的是前綴和預(yù)處理還有的是二分查找這四種思路之間幾乎沒有遷移性。你連著做五道數(shù)組題可能前三道用雙指針很順第四道是二分手感立刻斷掉。所以我采用的是“數(shù)據(jù)結(jié)構(gòu) 思維模型”的雙層分類。第一層保證你不至于在完全陌生的領(lǐng)域里硬碰第二層保證同一組題用的是同一套腦回路。75 道題分下來大概是這么個結(jié)構(gòu)分類層級覆蓋題型題量占比核心思維模型數(shù)組與字符串查找、替換、原地修改、子串約 18%雙指針、原地寫、滑動窗口鏈表反轉(zhuǎn)、合并、刪除、環(huán)、復(fù)制約 14%指針重連、快慢指針、啞節(jié)點棧與隊列單調(diào)棧、輔助棧、滑動窗口最值約 9%后進先出、單調(diào)性維護樹遍歷、重建、子結(jié)構(gòu)、路徑約 17%遞歸定義、返回值語義查找與排序二分變體、TopK、歸并約 12%區(qū)間收縮、分治動態(tài)規(guī)劃線性 DP、區(qū)間 DP、計數(shù) DP約 16%狀態(tài)定義、轉(zhuǎn)移方程、初始化回溯與搜索排列、組合、矩陣路徑約 8%選擇與撤銷、剪枝位運算與數(shù)學(xué)計數(shù)、快速冪、進制約 6%位運算性質(zhì)、數(shù)學(xué)推導(dǎo)這張表你可以直接當(dāng)目錄用。占比不是隨便寫的它對應(yīng)的是面試出題頻率的大致分布——數(shù)組字符串和樹加起來超過三分之一這兩塊練不透其他部分再熟也撐不住場面。2.2 分類之后必須做的事給每類找一道“母題”分類只是第一步。真正讓分類產(chǎn)生價值的是每一類里挑一道母題把它的解法吃到能默寫的程度。母題的作用相當(dāng)于一個模板庫的入口后面遇到同類題你只需要判斷“它和母題差在哪”而不是從零開始想。舉幾個我自己的母題選擇數(shù)組類的母題是“二維數(shù)組中的查找”——它把“有序性如何轉(zhuǎn)化為指針移動規(guī)則”這件事講透了后面做旋轉(zhuǎn)數(shù)組、矩陣置零都能套這個思路。鏈表類的母題是“反轉(zhuǎn)鏈表”——指針重連的三行代碼是所有鏈表操作的地基合并、分組反轉(zhuǎn)、回文判斷全是它的變體。樹類的母題是“二叉樹的鏡像”——遞歸的返回值語義、左右子樹交換的順序這一道講清楚了后面重建二叉樹、判斷子結(jié)構(gòu)都不會亂。DP 類的母題是“連續(xù)子數(shù)組的最大和”——狀態(tài)定義、初始化、轉(zhuǎn)移、邊界四個要素齊全而且短五分鐘能默寫一遍。母題選完之后每類題的第一道必須是母題而且要求做到不看書、不看提示、一次寫對。做不到就重來不要往下走。這個要求聽起來苛刻但它省掉的是后面幾十道題的反復(fù)卡殼時間。提示母題不是“最簡單的題”而是“最能代表這類題思維骨架的題”。簡單題未必有代表性有些簡單題只是邊界情況多思維含量低選它當(dāng)母題反而浪費時間。2.3 分類里容易踩的坑把“相似解法”當(dāng)成“同一類”有個坑我踩過不止一次看到兩道題都能用雙指針做就把它們歸成一類結(jié)果復(fù)習(xí)的時候一起復(fù)習(xí)考試的時候一起想不起來。原因是它們的雙指針目的不同——有的是為了縮小搜索區(qū)間有的是為了維護窗口內(nèi)某種性質(zhì)有的是為了原地寫覆蓋讀指針。判斷兩道題是不是真的一類我有個笨辦法合上題解用一句話說清楚“這道題的第一步?jīng)Q策是什么”。如果兩題的第一步?jīng)Q策是同一句話比如“先固定左端點右端點單調(diào)右移”那它們是一類如果一句話說不清或者兩題的第一步是不同的話那它們只是“解法看起來像”不該放在一起練。這個判斷標(biāo)準(zhǔn)比看標(biāo)簽靠譜得多因為標(biāo)簽是別人打的決策是你自己做出來的。3. 31 天路線圖的具體排布每天做多少、做什么、留多少緩沖3.1 排期的三個硬約束和對應(yīng)的參數(shù)計算排路線圖不能憑感覺說“每天兩道題”得先算清楚三個約束。第一個約束是總量。75 道題31 天平均每天 2.42 道。但新題不能天天滿負荷必須留復(fù)習(xí)位所以真實的分配是新題總量約 62 道復(fù)習(xí)位約 13 天次。剩下的十幾道題放在最后幾天的套卷和錯題回爐里不算新題。第二個約束是單題耗時。我實測下來的時間分布是這樣的一道沒見過的中等題從讀題到寫完并自測通過45 到 60 分鐘是常態(tài)其中讀題和理解 5 到 10 分鐘、獨立思考 10 到 15 分鐘、編碼 20 分鐘、對照題解和修正 10 到 15 分鐘。如果卡住了硬扛的上限是 30 分鐘超過就去看題解不要死磕。復(fù)習(xí)一道做過的題15 到 20 分鐘。第三個約束是精力曲線。工作日晚上能穩(wěn)定拿出 2 小時已經(jīng)很不錯周末能拿出 4 小時。所以排期必須做成“工作日輕、周末重”的節(jié)奏而不是每天平均切。按這三個約束算下來一個可執(zhí)行的日課表是這樣時段類型新題量復(fù)習(xí)量預(yù)估耗時工作日約 20 天2 道1 道100 到 120 分鐘周末約 8 天3 到 4 道2 道200 到 240 分鐘收尾階段3 天0 道錯題全量每天 90 分鐘62 道新題怎么落到這 28 天里工作日 20 天 × 2 道 40 道周末 8 天 × 平均 2.75 道 ≈ 22 道合計 62 道。剩下 13 道題分布在最后三天的錯題回爐和套卷里其中一部分是你第一遍沒做出來的題正好借這個機會補上。3.2 逐周拆解從基礎(chǔ)結(jié)構(gòu)到綜合套卷第 1 周Day 1 到 Day 7數(shù)組、字符串、鏈表。這一周的目標(biāo)不是做對多少題而是把“邊界條件”這個習(xí)慣建立起來。數(shù)組題最常見的錯是空數(shù)組、單元素、全相同元素鏈表題最常見的錯是空鏈表、單節(jié)點、斷鏈。這一周每天的新題里至少要有一道是“看起來很簡單但邊界很坑”的題逼自己養(yǎng)成寫完先手推三組測試數(shù)據(jù)的習(xí)慣。這一周的具體安排Day 1 到 Day 3 做數(shù)組與字符串母題 原地修改 雙指針 滑動窗口Day 4 到 Day 5 做鏈表基礎(chǔ)反轉(zhuǎn)、合并、刪除、倒數(shù)第 kDay 6 做鏈表的進階環(huán)、復(fù)制復(fù)雜鏈表、兩個鏈表第一個公共節(jié)點Day 7 全天復(fù)盤把這一周所有做錯的題重寫一遍不寫新題。第 2 周Day 8 到 Day 14棧隊列 樹。這一周是整個路線圖里最陡的一段因為樹的遞歸思維對很多人來說是第一次真正意義上的“思維轉(zhuǎn)換”。我的建議是 Day 8 到 Day 9 先把棧隊列解決掉兩個棧實現(xiàn)隊列、包含 min 的棧、棧的壓入彈出序列、滑動窗口最大值Day 10 到 Day 13 全部給樹Day 14 復(fù)盤。樹的四天要按順序來先遍歷前中后序、層序再重建前序中序重建、后序中序重建再性質(zhì)鏡像、對稱、子結(jié)構(gòu)、平衡最后路徑與二叉搜索樹路徑和、BST 轉(zhuǎn)雙向鏈表、BST 第 k 大。這個順序不能亂因為后一步全是前一步的復(fù)用。第 3 周Day 15 到 Day 21查找排序 動態(tài)規(guī)劃 回溯。這一周的關(guān)鍵詞是“模板”。二分查找要整理出至少三個變體模板找目標(biāo)、找左邊界、找右邊界DP 要整理出狀態(tài)定義的四要素模板回溯要整理出“選擇—遞歸—撤銷”的三行骨架。Day 15 到 Day 16 做查找排序二分變體、TopK、歸并、快速選擇Day 17 到 Day 19 做 DPDay 20 到 Day 21 做回溯。DP 這三天一定要按難度遞增排先線性 DP斐波那契類、跳臺階、連續(xù)子數(shù)組最大和再二維 DP禮物的最大價值、最長不含重復(fù)字符子串最后計數(shù)類 DP丑數(shù)、n 個骰子的點數(shù)。二維 DP 放到第二段是因為它需要先有“狀態(tài)是二維的”這個直覺一上來就做容易懵。第 4 周Day 22 到 Day 28位運算數(shù)學(xué) 綜合套卷。Day 22 到 Day 23 處理位運算和數(shù)學(xué)二進制中 1 的個數(shù)、數(shù)值的整數(shù)次方、1 到 n 整數(shù)中 1 出現(xiàn)的次數(shù)、數(shù)組中出現(xiàn)次數(shù)超過一半的數(shù)字這類題量少但思維跳躍大單獨放兩天比較合適。Day 24 到 Day 28 進入套卷模式每天隨機抽 5 道題限時 90 分鐘模擬真實面試的手感做完立刻復(fù)盤。收尾三天Day 29 到 Day 31錯題回爐 模擬面試。這三天不碰新題。Day 29 把整份錯題本過一遍只做第一遍沒做出來的那些Day 30 挑 8 道高頻題做口頭講解對著空氣講思路講不順的就是沒真懂Day 31 整套模擬隨機 3 道題白板寫限時 45 分鐘。3.3 復(fù)習(xí)位怎么插固定間隔比“想起來就復(fù)習(xí)”靠譜復(fù)習(xí)位的插入規(guī)則我用的是固定間隔做完一道新題的當(dāng)天晚上、第 3 天、第 7 天、第 15 天各復(fù)習(xí)一次。聽起來很麻煩實際上操作很簡單——每天開始新題之前先看看“今天該復(fù)習(xí)哪些”把該復(fù)習(xí)的題號列出來花 20 分鐘過一遍再開始新題。這個間隔不是我拍的它對應(yīng)的是遺忘曲線里幾個比較關(guān)鍵的衰減點。第 1 天復(fù)習(xí)是為了趁記憶還熱的時候加固編碼細節(jié)第 3 天復(fù)習(xí)是為了對抗第一次明顯遺忘第 7 天和第 15 天是兩次長間隔主要檢驗“思路還在不在”。實際操作中你會發(fā)現(xiàn)第 15 天那次復(fù)習(xí)最痛苦很多題你已經(jīng)完全忘了當(dāng)時怎么想的。這恰恰是它有價值的地方——如果第 15 天你還能獨立寫出來這道題基本就進入長期記憶了。寫不出來也不用慌標(biāo)記為“重點錯題”進最后的錯題回爐名單。注意復(fù)習(xí)不是“重看一遍題解”而是“合上一切從空白開始寫”??搭}解產(chǎn)生的熟悉感是假的只有手能寫出來才算數(shù)。4. 每道題做到什么程度算過關(guān)三遍刷題法和筆記模板4.1 三遍刷題法每一遍的目標(biāo)完全不同很多人刷題效率低是因為把“做過”當(dāng)成了“會了”。我的做法是每道題強制過三遍每遍的目標(biāo)不一樣。第一遍理解優(yōu)先允許看題解。獨立思考 20 到 30 分鐘卡住就看題解看完之后合上題解自己重寫一遍。這一遍的目標(biāo)是搞清楚“這道題的解法為什么成立”不是記住代碼。寫完要在筆記里寫一句話總結(jié)核心思路比如“先固定左邊界右邊界單調(diào)右移窗口內(nèi)維護不重復(fù)字符集合”。第二遍脫離題解限時完成。在第一遍之后的第 3 天左右進行要求完全不看任何提示25 分鐘內(nèi)寫完并自測通過。寫不出來就說明第一遍其實沒懂回到第一遍重來。這一遍的目標(biāo)是“能獨立復(fù)現(xiàn)”。第三遍限時壓縮模擬壓力。在第 7 天或第 15 天進行要求在 15 分鐘內(nèi)寫完邊寫邊口述思路。這一遍的目標(biāo)是“在緊張狀態(tài)下還能寫對”因為面試現(xiàn)場就是有壓力的平時寫得出、現(xiàn)場寫不出的人非常多。三遍都過的題標(biāo)記為“已掌握”后續(xù)只在套卷里隨機抽到才做。三遍里任何一遍沒過進錯題本按錯題本的節(jié)奏走。4.2 題解筆記的固定模板五欄多一欄都嫌多筆記記得太詳細復(fù)習(xí)的時候會忍不住通讀反而浪費時間記得太簡略復(fù)習(xí)的時候看不懂自己在寫什么。我用的是固定五欄每道題控制在半頁以內(nèi)欄目寫什么示例一句話思路第一步?jīng)Q策 核心不變式快慢指針快指針先走 k 步然后同步走關(guān)鍵邊界這道題特有、容易漏的情況鏈表長度小于 k 時返回空復(fù)雜度時間、空間寫清楚為什么時間 O(n)每個節(jié)點訪問兩次空間 O(1)踩坑記錄自己第一次寫錯在哪快指針先走時沒判空導(dǎo)致空指針異常同類遷移這道題的思路還能用在哪些題上可用于判斷環(huán)、找中點、找倒數(shù)第 k第三欄“復(fù)雜度”很多人會跳過覺得寫個 O(n) 就夠了。實際上把“為什么是 O(n)”寫清楚是檢驗自己有沒有真正理解循環(huán)結(jié)構(gòu)的唯一辦法。比如快慢指針那道題如果你寫不出“每個節(jié)點最多被訪問兩次所以是線性”說明你對指針移動次數(shù)的判斷還是模糊的。4.3 測試數(shù)據(jù)的構(gòu)造習(xí)慣寫完先手推三組這一條我要單獨拎出來講因為它是拉開差距的地方。大部分人寫完代碼就直接提交跑通了就過跑不通就瞎改。正確的做法是寫完先自己構(gòu)造三組數(shù)據(jù)手推第一組用最小規(guī)??蛰斎搿卧?、兩個元素專門用來撞邊界第二組用常規(guī)規(guī)模五到八個元素驗證主流程第三組用特殊結(jié)構(gòu)全相同元素、已排序、逆序、有重復(fù)值專門用來撞那些“看起來對但實際錯”的邏輯。鏈表題的手推尤其重要因為鏈表在紙上畫出來和腦子里想完全是兩回事。我的習(xí)慣是每次寫鏈表題先在紙上畫三個節(jié)點標(biāo)上指針然后按代碼一行一行挪指針看有沒有斷鏈。這個動作花兩分鐘能省掉后面二十分鐘的調(diào)試。5. 常見問題與排查技巧實錄那些文檔里不會寫的坑5.1 高頻卡點速查表下面這張表是我自己踩過、也見別人踩過的高頻問題按出現(xiàn)頻率排序。遇到卡住的時候先掃一遍很多時候問題就在里面?,F(xiàn)象最可能的原因排查動作本地跑通提交報錯邊界輸入沒覆蓋補測空輸入、單元素、極值結(jié)果差一位循環(huán)終止條件寫錯把和逐個核對畫出區(qū)間鏈表題結(jié)果少一個節(jié)點斷鏈或漏接尾部在紙上畫出指針變化檢查最后一步遞歸題棧溢出遞歸深度過大或缺少終止條件檢查終止條件是否覆蓋所有分支DP 結(jié)果偏大或偏小初始化或轉(zhuǎn)移方向錯手推前三個狀態(tài)看是否符合預(yù)期二分查找死循環(huán)區(qū)間收縮方式不統(tǒng)一固定一種區(qū)間寫法不要中途換字符串題結(jié)果亂碼原地修改時覆蓋了未讀部分檢查讀寫指針的先后順序回溯結(jié)果重復(fù)沒做去重或選擇順序亂排序后加同層去重判斷這張表里最值得說的是“二分查找死循環(huán)”因為它太常見了。根因幾乎永遠是區(qū)間定義不統(tǒng)一一會兒用左閉右閉一會兒用左閉右開收縮的時候left mid和left mid 1混著用必然死循環(huán)。解決辦法很土但有效——整份代碼只允許用一種區(qū)間寫法寫之前先在注釋里寫明是左閉右閉還是左閉右開寫完對照注釋檢查每一處收縮。5.2 時間不夠用怎么辦三條降級策略31 天聽著長實際執(zhí)行起來一定會有斷檔。加班、生病、臨時有事斷個兩三天太正常了。這時候不要想著“補回來”補不回來的硬補只會導(dǎo)致后面全部崩盤。我用的是三條降級策略按優(yōu)先級排第一條砍新題不砍復(fù)習(xí)。時間緊張的時候?qū)幙山裉觳蛔鲂骂}也要把該復(fù)習(xí)的復(fù)習(xí)完。因為新題是增量復(fù)習(xí)是保值保值優(yōu)先。第二條把大題拆成兩半。一道題想 30 分鐘沒思路不要硬扛到 60 分鐘直接看題解的前半段只看思路不看代碼然后自己寫。這樣單題耗時能壓到 30 分鐘以內(nèi)雖然理解深度打折但至少保持了節(jié)奏。第三條整周順延但壓縮收尾階段。如果某一周整體崩了就把這一周的內(nèi)容順延到下一周同時把最后三天的收尾壓縮成一天。套卷和模擬面試可以砍錯題回爐不能砍因為錯題才是你真正的薄弱點。有一點要提醒不要為了趕進度而跳過復(fù)盤日。第 7 天、第 14 天、第 21 天這三個復(fù)盤日看起來“沒做新題好像虧了”實際上它們的價值比做三天新題還高。復(fù)盤日做的事情是把這一周的錯誤模式提煉出來比如“我這周所有鏈表題都錯在沒判空”這個發(fā)現(xiàn)能一次性修掉后面十幾道題的同類錯誤。5.3 反復(fù)忘怎么辦把“記不住”拆成三種情況“做完就忘”是這個路線圖里被問得最多的問題。我的觀察是它其實是三種不同的問題處理方式完全不一樣。第一種是編碼細節(jié)忘。思路記得但邊界怎么寫、循環(huán)怎么起忘了。這種情況不用重做整道題只需要默寫核心代碼段三到五行兩分鐘一遍。比如快慢指針的循環(huán)骨架、二分的區(qū)間收縮兩行、DP 的初始化三行這些是肌肉記憶靠高頻短練解決。第二種是思路忘??吹筋}完全想不起從哪下手。這種情況說明第一遍就沒真懂必須回到第一遍重做而且要看當(dāng)時寫的“一句話思路”對照著重新推一遍。如果推完還是模糊說明這道題的母題沒吃透回去重做母題。第三種是同類題遷移不了。母題會做變體不會。這種情況最容易被誤判成“記性差”實際上是沒有做過變體對比。解決辦法是拿兩道同類題放在一起只比較“它們的第一步?jīng)Q策差在哪”寫成一兩句話。比如“連續(xù)子數(shù)組最大和”和“乘積最大子數(shù)組”差別就在于后者需要同時維護最大值和最小值因為負數(shù)乘負數(shù)會翻正。這種對比做三五組遷移能力會明顯上來。提示不要用“刷題數(shù)量”衡量進度。75 道題刷完三遍是 225 次有效練習(xí)刷一遍就過是 75 次這兩者的差距不是三倍是十倍以上。5.4 面試現(xiàn)場的三條應(yīng)急技巧最后分享幾條真正在高壓場景下用得上的東西都是我被坑出來的。第一條先講暴力解再優(yōu)化。拿到題不要悶頭想最優(yōu)解先用一句話把暴力解說出來“最直接的做法是兩層循環(huán)枚舉所有組合復(fù)雜度 O(n2)我先說這個保證有解然后再看能不能優(yōu)化?!边@句話的作用是給面試官一個“這個人有基本盤”的信號同時也給自己爭取了思考時間。第二條寫代碼前先復(fù)述一遍輸入輸出和邊界。比如“輸入是一個可能為空的鏈表頭節(jié)點輸出是反轉(zhuǎn)后的頭節(jié)點如果輸入為空我返回空”。這個動作看起來啰嗦但它能擋掉一半以上的邊界錯誤而且面試官很吃這一套。第三條卡住的時候說出你在想什么。沉默是面試里最危險的狀態(tài)。哪怕你只是在想“這個能不能用雙指針”也要說出來。面試官不怕你想不出來怕的是不知道你在想什么沒法給你提示。6. 路線圖跑完之后的延伸方向31 天跑完 75 題只能算把地基打完。后面的延伸我一般建議兩個方向按需選一個就行不要貪多。一個方向是往同類題庫擴展。75 題里的每一類都能在更大的題庫里找到同模型的變體比如樹類做完之后去刷層序變體、路徑變體DP 做完之后去刷區(qū)間 DP 和狀態(tài)壓縮。擴展的時候不要重新分類直接往已有的分類里塞塞不進去的說明是新模型單獨記一筆。另一個方向是往表達能力上轉(zhuǎn)。做題做多了會發(fā)現(xiàn)寫得出和講得清是兩回事。我自己的練法是挑十道高頻題每道題錄一段三分鐘的語音講清楚思路、復(fù)雜度、邊界然后回放聽。聽的時候重點聽兩個地方有沒有卡頓有沒有說“然后這里就……嗯……”??D的地方就是理解不牢的地方回去補。這兩個方向不用都做選一個跑兩周效果比繼續(xù)盲目刷新題明顯得多。我當(dāng)時是選的第一條因為手上還有面試要準(zhǔn)備擴展題庫的性價比更高如果是已經(jīng)工作、想長期保持手感第二條更合適畢竟日常工作中講清楚一個方案比寫出一個算法更常用。