这套刷题大纲的价值,不在于它列了多少道题,而在于它把“算法面试准备”这件事从一团乱麻整理成了一条可以照着走的路线。很多准备技术面试的朋友都听说过“代码随想录”这四个字,甚至在各种经验帖里看到过别人推荐,但真正打开之后反而容易迷茫——目录那么长,专题那么多,到底先刷哪个后刷哪个?每天刷几道才合适?刷到什么程度算过关?这些问题如果没人给个框架,很容易演变成“打开题单、点开第一题、看不懂答案、关掉页面、陷入焦虑”的死循环。这篇内容就是围绕这套经典刷题大纲和清单,讲清楚它背后的结构逻辑、每个模块的侧重点、以及我在按这个清单实操过程中踩过的坑和总结出来的方法。
先说清楚这套大纲是干嘛用的。它本质上是一份为应付算法面试(笔试、技术面手写代码)而设计的学习路径,把面试中最高频的数据结构和算法题型拆成了若干个专题,每个专题配套若干道经过挑选的经典题,并给每道题写了思路讲解和参考代码。它解决的核心问题是:大多数人不是不会写代码,而是面对海量题库不知道练什么、按什么顺序练、练到什么程度。有个明确的清单,至少能把“学算法”这个模糊目标,变成“按专题逐项打卡”这种可执行的动作,减少决策成本,也就减少了一开始的畏难情绪。
不过很多人对这份清单有个误解,觉得它就是一份“题库合集”,答案背熟就行了。实际上,如果只是背答案,这份清单的价值会大打折扣。它的真正设计意图是让刷题的人按专题建立“解题模式”,比如看到“在有序数组里找一个数”就反射性想到二分,看到“连续子区间求和”就想到前缀和或滑动窗口,看到“括号匹配”就想到栈。这种条件反射式的识别能力,才是面试手撕代码时真正需要的东西。所以这篇内容会从大纲结构、专题重点、实操流程、避坑指南四个维度展开,尽量把这份清单讲透。
1. 大纲的地图:专题顺序与它的底层逻辑
1.1 整体目录结构长什么样
代码随想录的专题划分,基本是按“数据结构 + 算法范式”组合展开的,常见的顺序大致如下:
- 数组与循环:二分查找、双指针、滑动窗口、模拟题
- 链表:反转、环的检测、合并、删除等指针操作
- 哈希表:用哈希计数、查找配对、去重
- 字符串:反转、替换、KMP、字符串匹配
- 双指针法:相向指针、快慢指针在数组与链表中的综合应用
- 栈与队列:括号匹配、单调栈、优先队列相关模型
- 二叉树:遍历、层序、属性计算、公共祖先、搜索树操作
- 回溯算法:组合、排列、子集、切割、棋盘搜索
- 贪心算法:区间调度、分配问题、单调递增数字类问题
- 动态规划:背包、子序列、编辑距离、股票买卖、打家劫舍等
- 图论:深度优先搜索、广度优先搜索、拓扑排序、并查集
- 补充专题:位运算、单调栈应用、前缀树等
清单里每个专题下通常有少则三五道、多则十余道题目,加起来是一份庞大但可控的题量。对比动辄上千道的题库,这份清单的筛选逻辑很明确:不是按题库编号平铺,而是按“题型代表”选例,每道题都尽量承载一类解法模板,做熟一道就能迁移到同类衍生题。
1.2 为什么顺序这样排,而不是从难到易
很多初学者拿到清单,第一个念头是想直接跳到回溯和动态规划,觉得这些才是“高级题”,前面数组哈希太基础,刷起来不过瘾。但从大纲设计者的角度,这个顺序不是随意定的,而是遵循“前置知识依赖”的递进关系。
举个例子,二叉树的题目大量使用递归,而递归思维一开始要通过链表反转、数组拆分这类场景来预热,如果跳过链表直接上二叉树,会同时在“递归调用怎么return”和“树的遍历框架”这两个问题上卡住,很难定位真正的薄弱点。双指针专题也是这样:在数组里理解快慢指针只需要下标移动,比在链表里操作 next 指针更直观,先把数组里的滑动窗口练熟,再去链表找环就顺畅得多。哈希表更不用说了,后续几乎所有“空间换时间”的优化思路都依赖它,如果哈希表不熟练,做题时的复杂度优化几乎无从谈起。
所以这份清单的排序,本质上是把算法学习拆成了“先数据结构、后算法策略、再复杂综合”三个阶段。第一阶段(数组、链表、哈希、字符串)解决“用什么容器存数据”的问题,第二阶段(栈、队列、二叉树)开始感受递归和层级的抽象,第三阶段(回溯、贪心、动态规划、图论)才是真正的算法设计能力训练。
1.3 它和力扣题库的关系、以及不同人群的使用策略
可以把它理解为一份经过人工过滤的力扣精选集,但比力扣官方榜单更偏“国内技术面试”。它选择的题目整体以经典题型为主,难度曲线相对平滑,不会出现链表专题里蹦出一道需要红黑树知识才能解的变态题。这样的设计,对以下几类人群比较友好:
- 正在准备大厂实习、校招或跳槽社招的开发者,需要笔试面试手撕代码
- 自认为基础不牢,打算系统梳理一遍数据结构和算法的新手
- 已经零散刷过不少题,但总觉得脑袋里没形成体系,想做「归并整理」的进阶者
同时也要说句实在话,它并不适合纯算法竞赛玩家。竞赛题目讲究思维量和代码技巧的极限压榨,而这份清单的目的是“面试够用、体系完整”,所以很多题目在竞赛视角下偏基础。如果你目标只是通过技术面试,而不是拿比赛名次,那这份清单的性价比非常高。
2. 几个重点专题拆解:到底在练什么
2.1 数组、哈希与双指针:几乎所有题的地基
这一阶段的题,表面看是在练“简单题”,实际上是在练两件事:一是手速,二是对复杂度优化的敏感度。数组专题里的二分查找看似基础,但它的边界条件(左闭右开、左闭右闭)足够让很多一年经验以上的开发者在面试翻车。我自己的感受是,二分模板必须固定成自己习惯的一种写法,不要这次用 left = mid + 1,下次又用 left = mid,最后在面试现场临时推边界,非常容易出 bug。
哈希表的精髓在于“空间换时间”的取舍。经典题“两数之和”,第一反应写暴力双层循环很简单,但面试官几乎必然会追问“能不能 O(n)”,这时候能立刻想到用字典记录已遍历过的值和下标,才是真正的考点。这种现象在后续题目里反复出现,哈希表用得熟不熟练,直接决定能不能写出符合面试预期的复杂度解。
双指针专题则是对数组操作的综合体操。快慢指针、左右对撞指针、滑动窗口三种模式,几乎覆盖了子数组、子串类问题的基础分析框架。练习时不用贪多,而是把每种模式吃透。例如滑动窗口的思路就是“右边界扩张,左边界收缩”,看起来只是两个下标移动,但真正要写对while条件的场景其实非常多,必须靠练习形成肌肉记忆。
2.2 二叉树:递归思维的集中训练场
二叉树专题是很多人的分水岭,因为从这开始题目的“可背性”变弱了,开始考验是否真正理解递归。做题之前,先去统一理解递归的“三步法”:确定递归函数的参数和返回值,确定终止条件,确定单层递归的逻辑。这三个步骤听起来简单,但大多数二叉树题写不出来,就是在单层逻辑那里想复杂了,总想在一层递归里同时处理太多事。
二叉树里最值得反复练的首先是“遍历框架”。前中后序遍历都可以用递归写,但真正要理解的是非递归写法,因为很多思想(比如中序遍历在二叉搜索树里就是有序序列)会在后续题目里反复出现。层序遍历解决的是“按层处理”的问题,它扩展开来就是很多图论题目的雏形,所以值得把每一层的逻辑、如何标记层边界都搞明白。
之后是“属性计算”(深度、节点数、路径和、公共祖先)和“搜索树操作”(插入、删除、验证、最近公共祖先)。这些题表面各不相同,但底层都是在遍历框架上增加一点条件判断或返回值设计。练习时可以拿着同一棵树,用多种方法分别解同一个问题,比如求二叉树的最大深度,既可以用递归后序遍历,也可以用层序遍历记录层数,亲自动手对比一次,会对递归和迭代的理解更深。
2.3 回溯:暴力搜索的结构化表达
回溯算法是最容易让人“听懂了但写不出来”的专题。它的核心是递归 + 撤销操作,整个框架其实非常固定:
- 在递归函数中先判断是否到达终止条件
- 然后遍历当前可选择的所有元素
- 做选择,进入下一层递归
- 递归返回后撤销刚才的选择
以全排列和组合这两类经典题为例,真正容易出错的其实只有两点:一是如何去重(是排序后跳过相邻相同元素,还是用集合记录当前层用过的元素),二是组合剪枝的边界条件(剩余元素不够时提前终止)。把这两点想清楚,回溯的大多数题都能套进同一个框架。
练习回溯专题时,建议用“画树形图”的方式辅助思考。每一层递归表示一层选择,分支表示候选元素,路径上的组合就是最终结果。我见过很多人对着代码空想,怎么也想不通为什么某个if条件写在循环外还是循环内,这时只要把递归树画出来,答案基本就直观了。
2.4 动态规划:最需要“先懂原理再刷题”的关卡
动态规划是清单里体量最大、也最劝退的专题。它不像回溯有相对统一的框架抄,每一类题(背包、子序列、爬楼梯、编辑距离、打家劫舍)的状态定义、转移方程、遍历顺序都长得不一样,很容易让人做一道忘一道。
我的经验是:动规题入门阶段,先不要急着海量刷题,而是把“五步法”练到产生肌肉记忆。这五步是:确定dp数组(或dp函数)的含义、确定递推公式、初始化dp、确定遍历顺序、打印dp数组验证。
以最基本的爬楼梯为例:
dp[i]表示爬到第i阶有几种方法- 递推公式是
dp[i] = dp[i - 1] + dp[i - 2] - 初始化为
dp[1] = 1, dp[2] = 2 - 遍历顺序显然是从 3 到 n 正序执行
- 最后打印一遍确认数值与手算一致
这套过程看上去非常简单,但真正遇到二维状态时,很多人就乱了。比如 0-1 背包问题,dp[i][j]表示前i件物品放入容量为j的背包能获得的最大价值,递推公式要区分“放不下第 i 件”和“放得下但选择不放”的情况。如果能严格按五步法推演,每一步都写清楚,而不是直接去背别人给的模板,动规会越练越有感觉。
动规专题里还有一批“可模板化但必须理解模板”的问题,比如背包模板、子序列模板。关键区别在于遍历顺序是正序还是倒序、dp是一维还是二维,这些都和状态压缩有关。我建议初学时不要一上来就用一维压缩写法,先把二维数组写明白,再去看一维优化是怎么把“上一行”的状态留在原地的,否则容易写出看起来正确但无法解释的代码。
3. 实操:把这套清单真正用起来的完整流程
3.1 建立自己的刷题仓库,而不是光在网页上过一遍
我见过很多朋友刷题,全程都在网页上打开题目、运行通过、关闭,再过两周回头看,什么都不记得。这样刷一百道和刷十道的信息留存差不了太多。更好的做法是建立一个本地代码仓库(用 Git 管理),按专题建目录,每一道题保存一个文件。
文件命名推荐包含日期与题目标识,比如:
arrays/ 2025-01-10_binary-search_704.py 2025-01-10_two-sum_1.py linked-list/ 2025-01-11_reverse-linked-list_206.py每道题的文件里,自己写清楚:
- 题目链接、题目简单描述
- 自己的解题思路与复杂度分析
- 参考解法或优化思路(可选)
- 这次踩到的坑(语法、边界、思路偏差)
这样做有几个看得见的好处。第一,复习时不用重新读题,看自己的注释就能回忆整个思路。第二,逼自己用文字把“为什么这么做”写出来,这个过程本身就是把短时记忆变成长期理解。第三,面试前可以按专题翻仓库,比上题库里重新找题高效得多。
3.2 单题完成的四个标准:不只“过了”就算完
在仓库里记录时,我给自己定了一个单题完成标准,四个条件缺一不可:
- 能独立写出代码,不借助题解,运行通过。
- 能口头说清楚时间复杂度与空间复杂度,并解释为什么是这个复杂度。
- 能回答“如果数据量变大/变小,解法会有什么问题”。
- 能至少说出一种和当前解法不同的思路。
每个专题刷完后,做一个自测:随机摘几道之前做过的题,不查资料、不看仓库,直接写。能写出来的题才是真掌握,写不出来的标记为“待复习”。这个自测阶段往往比新做题更能暴露问题。
3.3 时间安排:日拱一卒,别想一口吃成胖子
刷题最怕的是前三天热血沸腾,一天刷十道,到第四天因为某道题卡了两个小时直接放弃。比较可持续的安排是“1 + 1 + 0.5”模式:
- 每天一小时:刷一道新题,如果一道题超过半小时还没有完整思路,就标记为卡住,看题解并理解透彻,然后隔天重做。
- 每天一小时:复习老题,从仓库里挑三道以前做过的题目快速写一遍,重点看边界条件是否还记得。
- 每天半小时:整理当天的笔记,写复盘记录,尤其是“为什么会卡住”“卡在哪个知识点”。
这样算下来,一天两到三个小时对上班族来说已经不少了。但好处是每天都处于“新知识 + 旧知识复习”的循环里,而不是“瞎闯新题”的循环。
3.4 复习策略:对抗遗忘曲线
再好的清单,不复习等于白刷。我用的是间隔重复策略,和背英语单词一个道理。一道题做完后,按以下节奏回访:
- 第 1 天:重做一遍,关注能否不卡壳写完
- 第 3 天:只看题目和注释,尝试复述思路
- 第 7 天:闭卷重写一次代码
- 第 30 天:随机抽取一次做压力测试
这套节奏在不对照题解的前提下,能把一道题真正内化。大家不要觉得“这题我都做过了,还要重写一遍太浪费时间”,实际上重写的过程会不断巩固解题模式,而模式比单题重要得多。
4. 常见问题与避坑技巧
4.1 问题速查表
| 症状 | 可能原因 | 应对方法 |
|---|---|---|
| 一道题看了题解还是看不懂 | 前置知识点没打通 | 退回上一个关联专题补齐基础,不要硬扛 |
| 能看懂题解,但自己写不出来 | 缺少从思路到代码的转化训练 | 先别看代码,只看思路提示,自己尝试写一遍 |
| 写出来了但一提交就超时 | 复杂度不达标,或没有用上哈希表等缓存技巧 | 先从暴力解开始,再逐步优化,对比复杂度差异 |
| 每道题都要现场想很久才有思路 | 题型模式积累不足 | 增加复习频率,按模式归纳错题 |
| 动态规划总是做不出来 | 试图直接绕过“五步法”套模板 | 每道动规题都手写状态转移过程,不要略过推导 |
| 刷完感觉好像什么都没学 | 没有整理、复盘、重写 | 建立仓库笔记,用“输出”检验掌握情况 |
4.2 几个真实的坑与我的处理体验
第一个坑:贪多嚼不烂。我见过不少同学在数组专题还没刷完时,就开始跟风刷动态规划,结果两边都没刷透。动态规划的题目有一个特点,就是看题解觉得特别简单,但答案给的是别人的逻辑,自己脑子里根本没有建构出“为什么这么定义状态”的过程。这时候硬刷完清单,也只是完成了“把题号从列表里划掉”的目标,并没有完成“建立解题能力”的目标。正确做法是,当某个专题正确率低于七成时,先停下来把该专题的题目重新整理,直到大多数题都能独立写出为止,再进入下一个专题。
第二个坑:只刷不做笔记。很多刷题模版看起来严谨,其实只有两行代码复制粘贴,解题思路一条都没有写。这样的刷题记录在面试前完全起不到复习作用。后来我把每一道题都要求自己用三句话把思路写下来:一句话说明问题类型,一句话说明核心解法,一句话说明时间复杂度。这个习惯虽然增加了单题的耗时,但长期看非常值得。
第三个坑:死磕一道题太久。卡住不等于值得硬扛,很多时候卡住的点是某个小的知识盲区,比如不知道 Python 里怎么快速统计字符频率,或者不知道排序的lambda写法,这类问题与其花一小时硬想,不如直接看题解把盲区补上,然后立刻亲手写一遍。真正的学习发生在“补盲区之后的重做”中,而不在那一个小时的干耗里。
4.3 关于题目数量与强度的个人建议
很多人会问:“这份清单一定要全部刷完吗?”我个人认为,如果时间充裕当然建议完整过一遍,因为专题之间的关联非常紧密,完整的过程能建立闭环。但如果你离面试只有两周,那就没必要死磕图论和高级动态规划,把数组、链表、哈希、二叉树、回溯这几个核心专题的经典题刷两遍,性价比显然更高。
另外一个容易被忽略的点是:不要过早依赖题解甚至背代码。背代码在短时记忆里很有效,但面试时稍微变换一下题目条件(比如从升序改成包含重复元素),如果只背不理解,便会立刻崩盘。所以即使遇到很难的题,也应该先尝试用自己的话把思路写下来,再去看题解对照,而不是直接代码抄一遍就算掌握了。
5. 最后的经验总结:用输出倒逼输入
整套清单刷下来,我最大的感受是:刷题这件事,最重要的不是做了多少遍,而是你合上答案之后还能不能把它讲清楚。这套大纲的价值在于帮大家划定了边界,让人不再面对上千道题无从下手。但任何一份好的清单,最终都要靠你自己把它转化成自己的笔记、自己的代码、自己的习惯,才真正有意义。
在学习过程中,我习惯每隔几天就找身边朋友假装面试官,出一道已经做过的题,让我当场讲思路并写代码。这个过程比低头闷刷一个月的收获都大,因为它直接暴露了“我以为会了”和“我真的会了”之间的差距。刷这套大纲时,也可以试着这样给自己制造输出机会,难度不高,但效果非常好。另外一个小技巧是:每个专题结束建一个“模式清单”,例如“什么时候用双指针”“什么时候用单调栈”“遇到子串问题先想哈希和滑动窗口”等等,用一两句话写下来,面试前临时翻一翻会心安很多,也比反复刷题更应急。