1. 刷了大半年没起色,我把所有题重新编了一份算法刷题目录
1.1 为什么刷题容易"刷了个寂寞"
先说结论:算法刷题目录不是简单的待办清单,而是一张带索引、带注释、带复习节奏的知识地图。我见过不少人刷题很勤奋,两个月做了两百题,但一到面试或者实际项目里遇到算法场景,只能想起"我好像做过类似的题,但解法忘了"。这种状态有个很准确的形容——刷了个寂寞。问题的根源不在题量,在于所有做过的东西都是一次性消耗品,做完即丢,没有沉淀。
我第一次有意识去整理算法刷题目录,是在刷题大概八个月的时候。当时翻看自己的提交记录,发现很多题做了不止一遍,却分别在三个月前和两周前各做一次,中间没有形成任何关联。尤其像动态规划这类题,第一次做没懂,第二次做又是重新开始,等于把同样的折磨重复了两遍,浪费时间还打击信心。后来我花了两个晚上,把所有做过、做错、看题解的题全部拉出来,按专题分类,给每道题标注核心解法、难度、易错点、关联题目,再排成一份可迭代的目录。之后第三轮按这份目录刷,效果完全不一样——遇到新题能主动归类到某个专题,思路的启动速度明显变快。
如果你现在正处于"每天刷题但心里没底"的状态,那大概率不是不够努力,而是缺少一层抽象:把具体题目上升为专题套路。算法刷题目录提供的正是这层抽象,它把几百道零散的题,收敛成十几个专题下的若干种解法模式,让你在有限时间内积累起可迁移的解题能力。
1.2 目录到底解决了什么,适合谁来用
这份目录解决的问题,可以总结成三个词:遗忘、失联、无节奏。遗忘很好理解,不做复习一定会忘;失联指的是做了新题却不知道它和旧题的关联,明明同一个解法换了个包装就不认识了;无节奏则是没有安排复习的优先级,哪道题看缘分,最后全凭运气。一份合格的刷题目录,分别对应解决这三个问题:分类对抗遗忘,关联笔记对抗失联,熟练度标记对抗无节奏。
适合使用这份目录的人有三类。第一类是"刷了不少题但总感觉没体系"的中级选手,刷题量已经上去了,但知识停留在碎片的层面,需要一次系统性的归档。第二类是准备面试、需要在短时间内回顾高频考点的求职者,目录里的专题优先级和精品题清单能帮他们快速定位重点。第三类是想要把算法真正内化成工程能力、而不是只为了过面试的开发者,他们需要的是理解每个专题背后的思想,并在项目设计里灵活调用。
需要说明的是,这份目录的底层逻辑不绑定任何具体刷题平台。我在文中提到所有专题和题型,都来自通用的算法知识框架,无论你是用哪个在线题库,按这套结构去二次整理都能复用。平台只是载体,真正的价值在于组织信息的思路。
2. 建目录之前,先想清楚三条线:主线、副线和复习线
构建自己的算法刷题目录时,最容易犯的错是一上来就按"题目序号"或者"刷题日期"排一张大表。这种目录本质上是个流水账,看起来记录了所有题,实际没有任何结构化,检索全靠翻。我在重构目录的时候,把内容拆成了三条独立的线,分别对应三种不同的用途,这个顶层设计是后面所有操作的地基。
2.1 主线:按数据结构和算法思想铺专题
主线是目录的骨架,承担"把一道题放进正确抽屉"的功能。我采用了两层主线,而不是单层分类。
第一层按数据结构走:数组与字符串、链表、栈与队列、哈希表、二叉树、堆、图。这个顺序基本符合我们接触编程时认识数据结构的顺序,也符合各专题之间相互依赖的关系。比如栈和队列学扎实了,再去碰单调栈、优先队列和图的层序问题,理解成本会低很多;数组里的双指针和链表里的快慢指针,本质上是同一套思维在不同结构上的应用。
第二层按算法思想走:枚举、递归、二分、排序、双指针、贪心、回溯、动态规划、分治。算法思想跟数据结构是两个维度,所以我不会把它们混在同一个分类里,而是做成一个平行标签。比如"二叉树的中序遍历"在主线上属于二叉树,在标签里同时打上"递归";"最长递增子序列"主线上属于动态规划,标签里打上"二分查找"。这么设计的好处是,后期既可以按数据结构刷,也可以按算法思想刷,一本目录相当于两本索引。
2.2 副线:经典题、模板题与变式题
主线解决"分类"问题,副线解决"关联"问题。副线包含三类条目,它们共同决定了目录的横向延展度。
模板题是某一类专题中最有代表性的那道题,比如二叉树的层序遍历、快速排序的数组划分版、最基础的单源最短路径。这类题的特点是解法通用、变形多,值得反复手写。我第一次把模板题单独拉出来之后,发现自己之前做题根本不分主次,难题简单题一起刷,导致最简单的骨架题反而没有形成深刻印象。
经典题是面试和竞赛中被大量引用的题目,它们往往集多个知识点于一身,比如"编辑距离"涉及字符串和动态规划,"接雨水"涉及单调栈和双指针。这类题我会重点标注"知识交叉",因为做它们可以一次性复习多个专题。
变式题是同一道模板题换了条件、换了数据范围之后的版本,可能难度更高或者需要额外优化。副线最关键的作用,是在做变式题时能快速反查到模板题和相关题组,形成"一类题"而不是"一道题"的认知。你会发现,所谓难题,本质上是多个模板题组合之后的结果。
2.3 复习线:给目录加上时间戳和熟练度
目录如果只有分类,没有时间维度的信息,用起来还是会乱。每条记录我保留了三个字段:首次遇见时间、最近一次复习时间、熟练度标记。熟练度只分三档:能快速写出、看提示能写、完全卡住。
这三个字段的作用是为复习决策提供依据。完全卡住的题自然优先级最高;看提示能写的需要重做一轮;能快速写出的题,可以根据时间间隔决定是否延长复习周期。熟练度不是用来跟别人比较的,它只服务于自己的复习节奏。我曾见过有人把熟练度做成百分制,弄得像绩效打分一样,反而增加了心理负担,完全没有必要。
三条线的关系可以这样理解:主线告诉你"是什么",副线告诉你"和什么连在一起",复习线告诉你"该什么时间再看"。缺了任何一条,目录都会退化成列表。
3. 核心目录拆解:七个专题的编排逻辑与具体刷法
这一部分是整篇的重点。我会按个人目录中的顺序,把七个专题的编排逻辑、每类题的核心考点、以及推荐的刷题步骤讲清楚。你可以根据自己的薄弱项调整顺序,但大致骨架可以保持。
3.1 数组与字符串:双指针和滑动窗口的主场
数组是目录里最庞大的板块,也是后面一切专题的基础。这个板块里,按三层来收题。
第一层是纯数组操作:遍历、原地修改、排序变体、前缀和。前缀和是一个很好的起点,因为"子数组和等于目标值"这类问题,如果不用前缀和加哈希表,复杂度很难压到线性。第一次遇到时可能会觉得绕,但这是值得反复做的模板题。我特别在目录备注里写过一句话:前缀和数组的第i个位置,存的是原数组从0到i-1的所有元素之和。把这句话写清楚了,后面再遇到连续子数组的题,第一反应就自然切换到前缀和。
第二层是双指针,细分为相向双指针和快慢双指针。相向双指针最典型的场景是"两数之和变体""盛最多水的容器";快慢双指针的核心应用是"链表的环检测""数组里的重复数"。双指针的核心在于"为什么可以移动指针"——大多数时候,移动指针的本质是利用了单调性,排除了不可能成为答案的区间。这个"排除"的思维,比双指针的代码本身值钱得多。
第三层是滑动窗口,包含定长窗口和变长窗口。滑动窗口本质上是双指针的一种特化,但窗口大小变化逻辑需要单独吃透。拿到窗口题,先问自己三个问题:窗口的扩展条件是什么?收缩条件是什么?答案在扩大窗口时更新,还是在收缩时更新?把这三个问题写在目录备注里,同类题直接套。
字符串题我并不单独建一个大类,而是把它们拆到对应数据结构和算法里。例如"最长不重复子串"归到滑动窗口,"字符串匹配"归到双指针,"编辑距离"归到动态规划。这样做的原因是字符串本身没有独立的数据结构逻辑,强行单列会造成重复收题。
3.2 链表:指针操作是基本功,画图比代码更重要
链表题在面试里出现频率不低,而且代码量不大,是性价比很高的板块。目录里只保留三类,避免把时间浪费在过于偏门的变体上。
第一类是链表的基本操作:反转、合并、删除倒数第N个、链表中点。这些操作是后面所有链表题的基础,需要能脱离题解、在五分钟内写出无bug版本。我给自己定了一个硬性标准:反转链表必须手写三次以上,并且每次都能写对边界。刚开始觉得这是无用功,后来做"K个一组翻转链表"时才发现,基础反转的肌肉记忆能节省大量排查时间。
第二类是环与交点问题:判环、找环入口、找两个链表交点。这类题的核心是快慢指针,而快慢指针本质上是速度和距离的关系。理解"为什么快指针一定能在环里追上慢指针"比记住代码重要得多。我记得有个同事跟我说过,他能背出代码但解释不清,一追问就露馅。后来我专门在目录里记了一句:追及问题的判断条件是步长差而不是速度本身。
第三类是复杂场景题:排序链表、两数相加(逆序链表表示)、链表分组反转。这类题往往需要结合递归、栈或者归并思想,我会在目录里标注"前置依赖:递归、排序"。链表最值得写在目录里的经验是:先画图再写码。不是段子,是真的有用。指针操作中next被提前覆盖、pre和cur的先后顺序搞反,几乎每次都靠画图避免。我会在每条链表题备注里写清"哪一步最容易丢指向关系"。
3.3 栈与队列:单调栈与优先队列,一个管范围,一个管动态最值
栈和队列单独看起来很简单,但真正常考的是两个进阶结构:单调栈和优先队列,也就是堆。
单调栈解决的核心问题是"找每个元素左边或右边第一个比它大或小的位置",典型场景有"柱状图中最大的矩形""每日温度"。我在目录里给单调栈的核心笔记只有一句话:维护栈内单调性,弹出时结算答案。只要理解了这句话,所有单调栈题目基本是同一套骨架,变的只是结算的时机和记录的内容。这句话的推导过程是:当新元素破坏了单调性,说明栈顶元素遇到了第一个满足条件的新元素,此刻栈顶的答案就确定了。
优先队列解决的是"动态集合中的最值"问题,典型场景是"前K个高频元素""合并K个有序链表""数据流中的中位数"。使用它不需要研究堆的实现细节,但必须清楚两个问题:插入和弹出的时间复杂度各是多少、什么场景下堆的排序稳定性会影响答案。这两个问题决定了你用PriorityQueue还是别的数据结构,也决定你需不需要额外标注索引。
这两类题在目录里我会打上"高频"标签,因为它们在面试里属于"会的不难、不会的卡死"的类型。
3.4 哈希表:空间换时间的第一课
哈希表专题的体量不大,却是几乎所有优化问题的钥匙。它的核心考点集中在一点上:什么时候该用哈希表,把查找从O(n)降到O(1)。
按场景分成三小类。第一类是统计类问题:出现次数、频率排序、字符统计。这类题几乎一眼就能想到哈希表,关键是处理"多个统计结果同时维护"的技巧,比如同时维护最大值和次大值,或者在遍历过程中动态更新频率排序。
第二类是配对类问题:两数之和、四数相加、和为目标的最短子数组。如果只想到暴力枚举,复杂度很容易到O(n²)。用哈希表存储已经见过的元素或前缀和,就能把配对查找变成单次遍历。这个过程中有一个非常重要的思维转变:遍历到当前位置时,哈希表里存的是"过去"的信息,答案往往是"当前位置+过去信息"的组合。我在目录里标记这个思维为"空间换时间的基石"。
第三类是设计与模拟类:实现一个支持O(1)随机查找的结构、LRU缓存。这类问题表面叫设计题,本质上还是在考哈希表和链表或数组的协同。你可以把它们当成前面所有哈希表知识点的综合实践,放到中级阶段再刷。
3.5 二叉树与递归:先掌握遍历骨架,再谈各种变形
二叉树是收益最高的板块,因为树形结构能把"递归"这个算法思想展示得非常直观。目录里树的编排顺序是固定的,不推荐跳级。
第一步是四种遍历:前序、中序、后序、层序。前三种可以用递归实现,也可以改成迭代实现。我给自己下的任务是:用递归和迭代各写一遍,对比它们之间的差异。递归代码很简洁,迭代则需要显式维护栈,写一次就明白了系统栈是怎么工作的。层序遍历则是BFS在树上的首次落地,后面图的层序最短路径会反复用它。
第二步是基于遍历的修改类题目:翻转二叉树、二叉树的所有路径、最近公共祖先。这些题往往只需要在遍历过程中加一点额外的处理逻辑,但对理解"递归函数返回什么、在哪一层做操作"非常有帮助。做这一类题时,我会先写下"递归函数的语义是什么"再动笔,比如"返回以当前节点为根的子树的路径列表"或者"返回当前节点子树中是否存在目标节点"。
第三步是二叉搜索树相关:验证是否为BST、求第K小、BST转双向链表。BST的绝大部分题目都建立在"中序遍历后结果有序"这条事实上,把它写进目录的备注栏,后续做题直接套。
第四步是树的序列化与构建:根据前序中序重建二叉树、层序序列化。这类题的脑洞很大,但其实是在考"如何用递归去匹配两个序列之间的位置关系"。
3.6 动态规划:整个目录里最大的一块,也是唯一需要"状态设计"训练的板块
动态规划是我目录中分量最重的专题。它难不是因为代码复杂,而是因为"怎么想到这个状态定义"几乎没有固定套路可讲。我能给的建议是先把DP题目按照状态转移的特点分成几个子类,然后对每一子类吃透三到五道题。
第一类是线性DP:最长递增子序列、最大子数组和、打家劫舍系列。这类题的状态定义通常与"以当前位置结尾"有关,递推关系在相邻位置之间。第二类是两个序列DP:最长公共子序列、编辑距离。状态定义几乎是模板——用二维数组记录第一个序列前i个和第二个序列前j个位置的最优值,转移时讨论最后一个元素相不相等。
第三类是区间DP:最长回文子序列、戳气球。区间DP的特征是从小的区间递推到大的区间,二维数组的下标含义是两个端点的位置,转移时枚举中间的分割点。第四类是背包类:零一背包、完全背包、子集划分。背包问题的状态定义很固定,难的是把实际场景抽象成物品和容量。
第五类是从暴力递归改记忆化搜索的过渡题:三角形最小路径和、单词拆分。这类题我会先写递归版本,再改成带记忆数组的递归版本,最后才改成自底向上的递推版本。这个三步法对新手极友好,因为它让"状态转移"有了来源——不是凭空想出来的,而是从暴力的决策过程里提炼出来的。这个顺序也适合写进目录里作为备注:如果后来自底向上看不懂,就退回暴力递归版本。
DP板块在目录里的体量建议至少占四分之一。不要嫌多,后面的图论题里也会用到DP思想,这是值得投入的领域。
3.7 图论与回溯:把搜索空间建模成图,然后用DFS/BFS去遍历
图论板块是很多人的心理障碍,其实可以拆成清晰的几块。
第一块是图的表示与遍历:邻接表和邻接矩阵的区别、DFS和BFS的模板写法。这部分可以结合"岛屿问题"来练——网格里的连通分量看起来不是图,但当每个格子看作节点、上下左右看作边之后,就是标准的图遍历。这个抽象过程非常值得详细记录,因为大量图论题不会直接以图的形式给出。
第二块是最短路径:边权为1的情况下用BFS求最少步数,带权的情况下用优先队列或更进阶的算法。实际算法题里BFS版本考得最多,因为很多题把它包装成"从起点到终点的最少步数"。BFS的核心不只是遍历顺序,更重要的是它第一次到达目标节点时,路径一定最短。这个特性要写在目录里。
第三块是回溯:全排列、组合总和、N皇后。回溯本质上是带有撤销动作的DFS,我把套路总结成四步:选择、递归、撤销。任何回溯题,先画一棵"选择树"就能看清边界条件和剪枝时机。图论的代码模板性强,但难点在建模,所以我的目录里每一道图论题都有备注:"把什么建模成了什么"。比如"把每个单词建模成节点,把相差一个字母的单词建模成边"——这句备注比代码本身值钱得多。
4. 辅助目录:精品题清单、错题本和套路对照表
核心目录解决"按专题往里放题"的问题,但如果只有核心目录,第三轮复习时会发现题库太大,不知道从哪里入手。所以我在核心目录之外维护了三张辅助表,这是很容易被忽略但价值极高的部分。
4.1 每类专题的"必刷十题"清单
第一张辅助表是精品清单。做法是每个专题选十道题,十道题要覆盖该专题的所有核心考点,题与题之间尽量不重复套路。这十道题不是凭空选的,而是后来在整理核心目录时,发现有些题反复被当作"题解里的前置知识"引用,逐渐沉淀出来的,本质上是一个自然选择的过程。
这份十题清单直接决定了复习优先级。第一轮刷题时,核心目录里的题属于广撒网;但第二轮复习时,只刷十题清单里的题,因为它们代表性最硬。新遇到的同类题打进核心目录后,如果比清单里某道题更有代表性,我会替换掉旧题,让清单始终保持洗牌状态。这个"优胜劣汰"的机制,保证复习到的永远是当前认知下最优的一批题目。
4.2 错题本的标签体系:错因、卡点、耗时
第二张辅助表是错题本。但我的错题本不是简单把做错的题复制进来,而是每条记录包含三个标签:错因、卡点、耗时。
错因分为:没看懂题意、不会建模、逻辑细节写错、复杂度分析错误、看题解后仍不懂。卡点指的是具体卡在哪一步,比如"想到用双指针,但不知道收缩条件是什么"。耗时会记录第一次尝试持续了多久,超过三十分钟还没有任何进展就该看题解了——这一点自己硬扛未必值得。
错题本不是用来证明自己错了多少的,而是用来发现规律的。我做过一次统计,发现自己的错因里"没看懂题意"占了三成以上,这说明我读题太快,而不是算法弱。后续我强制要求自己先花三分钟把输入输出规则写出来,再动笔,错题率明显下降。一个小小的习惯调整,比多刷五十道题更有效。
4.3 套路对照表:把题解变成题感
第三张辅助表是套路对照表。它是一张两列表格,左列是问题特征,右列是推荐解法。下面给出我早期版本的一个简化示例:
| 问题特征 | 首选的思考方向 |
|---|---|
| 找子数组或子串的最值 | 前缀和、滑动窗口、二分答案 |
| 找配对关系 | 哈希表记录历史信息 |
| 答案是几个有序段的合并 | 双指针归并 |
| 枚举所有方案且需要去重 | 回溯加剪枝 |
| 问题可以拆成子问题且存在重叠 | 动态规划 |
| 图上有连通或距离问题 | BFS或DFS建模 |
这张表非常粗糙,但它是第一响应机制。每做完一道新题,都会回头看看它符合左列的哪个特征,如果答案选了和右列不同的解法,我会把新特征补进去。时间一长,左列越来越丰富,"看到题目 → 想到解法"的反应速度会明显提升。这种反应,本质上就是把显性的题解转化成了隐性的题感。
5. 目录驱动下的三轮刷题节奏:广度、深度、抽查缺一不可
目录建好之后,接下来的问题是怎么用它安排时间。我的经验是三轮刷题,每一轮对着目录的不同部分,三轮各司其职。
5.1 第一轮:按主线专题扫盲,目标是"见过"
第一轮按核心目录的顺序,从数组到图论,每个专题把基础题做一遍。这一轮不追求难题,甚至允许大量看题解。目标只有一个:让每个专题的核心模板题在脑子里留下印象,知道原来有这样一类问题,原来这类问题有这样一种主流解法。
第一轮最容易犯的错是贪多,在单个难题上耗太久。我的建议是单题不超过三十分钟,超过就标记为"卡住"并进入错题本,直接看题解。第一轮的精髓是速度,不是深度。有人担心看题解等于没做,实际上第一轮看题解不算"没做",只要你能在下一轮独立写出来,这个知识就已经是你的了。
5.2 第二轮:按辅助目录和错题本攻坚,目标是"掌握"
第二轮核心对象是两个:精品十题清单和错题本。精品题要做到熟练写出了再放过去;错题本里的题要独立重做一遍,确认上次卡住的点是否真正解决。
如果第二轮的错题重做还是卡,我会把这道题标注为"顽固题"。顽固题在目录里不做删除,而是单开一个小分组,等第三轮专门攻击。很多人第二轮刷着刷着就停了,就是因为不处理顽固题,挫败感太强。我的处理方式是:顽固题最多连续两轮失败,第三轮直接看题解并彻底背诵套路,然后过一个月再回访。绝大多数顽固题最后都能突破。
5.3 第三轮:按目录随机抽查,目标是"不依赖题号"
第三轮刻意不按专题顺序访问目录,而是用随机抽查或者乱序浏览。这是最接近真实考场状态的练习方式——你永远不会知道下一道题属于哪个专题,只能靠题目特征自己判断。
我会把目录导出成一张只有题名和题意的清单,随机抽,不按顺序写。这轮的核心指标是"看到题目后,多久能定位到正确专题"。如果超过两分钟定位不了,说明这道题的题干特征还没有对应到套路对照表,需要补记。
5.4 目录的动态调整机制
目录不是一日建成的,也不是一成不变的。我给自己定了几条调整规则:每完成一个新专题,就把该专题中最典型的题补充进核心目录;每发现一道新题同时覆盖两个专题的知识,就给它打多标签;每轮复习结束,对本轮一次未复习到的题目做冷热标记,热题代表高频或易错,冷题代表已完全掌握,下轮复习时冷题可以跳过。
特别想强调一点:目录里的题删除并不丢人,不要因为"这道题我已经刷过了"就强制保留。如果某道题已经能三次独立写出,熟练度标为已掌握,并且对复习没有帮助,完全可以移出本轮目录。目录的价值在于干净、可检索,而不是看起来数量多。凡是让目录膨胀到影响检索效率的内容,都是需要优化的对象。
6. 维护这份目录时踩过的三个坑,以及最终效果对比
最后写点实在的。这份算法刷题目录不是一次设计好的,中间反反复复调整过好几次,踩了几个挺有代表性的坑,写出来大家可以避开。
6.1 坑一:目录字段建得太细,维护成本高到放弃
第一次建目录时用了十几列自定义表格,字段包括题目编号、难度、分类、子分类、解法、复杂度、是否看题解、第一轮完成时间、第二轮完成时间……结果用了两周就坚持不下来了,因为每做一题光填表就要五分钟。后来我把字段砍到五个核心字段和三个复习线字段,才找到一个可持续的平衡。
适可而止很重要。目录是辅助工具,不能喧宾夺主。如果填表时间占到做题时间的二成以上,说明字段太多了。一个简单的判断标准是:如果某列信息在复习时从来不看,它就没有存在价值,建议删掉。
6.2 坑二:只记题目不记思路,目录成了一本"刷题流水账"
第二个坑是一开始只往目录里填题号和通过状态,导致三个月后翻看目录,除了"我做过这道题"以外什么也想不起来。这样的目录没有复习价值。后来我在每条记录里强制加入三行笔记:这题的考点是什么、解法的关键点是什么、如果再次遇到该提醒自己的点是什么。字数少则十个字,多则五十字,对复习效率的提升是立竿见影的。
比如"最长递增子序列"这道题,如果只记题号,复习时还是从头想;但备注里如果写着"末尾元素越小越好,所以可以用二分优化到O(n log n)",你扫一眼就能激活整个记忆链。笔记的价值不是解释给别人听,而是作为自己记忆的锚点。
6.3 坑三:只建目录不维护,让它烂在文档里
第三个坑更加隐蔽:目录建得很漂亮,但后面几周没有新的内容沉淀进去,慢慢就变成了一份静态文档。我现在把目录当作一个"活文档"看待:每次做完题当晚更新对应记录,每周末花二十分钟整理本周新增的变式题和错因统计,每月初做一次全量回顾并删减冷题。不要小看这二十分钟的周末维护,它让目录始终保持与最新认知同步。
6.4 最终效果:从"刷过"到"会做一类题"
把目录真正用起来之后,最明显的变化不是刷题数量暴增,而是定位能力变强。同样遇到一道没见过的题,之前我可能写十分钟又推翻重来,现在会在前两分钟内把它框进某个专题,再根据专题的套路表选思考方向。这种"具体题目 → 抽象专题 → 算法套路"的流程,正是算法刷题目录能带来的最大价值。
如果你准备开始建立自己的算法刷题目录,我的建议是从一个极小的版本起步:只保留分类、题名、考点、熟练度四个字段,先跑起来再说。不要一开始追求完美,目录是在迭代中变好的。等到第一轮刷完,再慢慢往里面加入错题引用、套路对照和精品清单,那时候你已经知道自己真正的需求在哪里了。上面这些内容,基本是我这一年多来沉淀下来的完整思路。如果只能从里面带走一句话,我会选这句:刷题让我们见多识广,而目录让我们见微知著,后者才是把刷题转化为真实能力的最后一公里。