day71(1.30)——leetcode面试经典150,这行字是我昨晚在打卡表里随手记下的进度。算起来,这套“面试经典150题”的计划我已经坚持了整整71天,平均每天2到3道,没有断档。今天这篇不想列代码,也不想讲某道具体题目的解法,而是想站在第71天这个节点上,认真做一次中期复盘:这150题到底在考什么、刷到中后段应该是什么状态、哪些专题最值得反复琢磨、以及我在这个过程中踩过哪些坑、修正过哪些错误的刷法。如果你也在用这套题单准备面试,或者正打算开始,这篇应该能帮你把路线看得更清楚。
1. 面试经典150题到底是什么
1.1 为什么是150道而不是3000道
面试经典150题不是从题库里随机抽的150道,也不是给算法竞赛选手准备的高强度训练集。它更像是一张经过反复筛选的高频考点地图,覆盖了绝大多数技术面试里真正会被问到的数据结构与算法知识点。它的定位非常明确:不追求让你达到竞赛选手那种“看到难题就能快速给出奇技淫巧”的水平,而是训练你在面试的有限时间内,做到三件事——快速识别题目类型、清晰说出解题思路、写出边界完整且风格干净的代码。
这一点决定了刷题方式不能走偏。竞赛题的评判标准是“快”和“巧”,面试题看的则是“稳”和“清”。很多人把面试准备做成竞赛训练,沉迷于研究偏题、难题、怪题,结果到了面试现场,连一道中等难度的数组题都讲不利索。150道这个数量也很有讲究,它足够覆盖主要考点,又不是靠无脑堆量就能混过去的规模。对大多数目标明确的人来说,与其在几千道题里东一榔头西一棒子,不如把这150道吃透,再在薄弱环节做定向补充。
1.2 150题覆盖的考纲地图与优先级拆解
刷到第71天,我最大的感受是这套题单的模块划分非常成体系。按照我个人的记忆和刷题记录,它大致包含下面这些板块:数组和字符串、双指针、滑动窗口、哈希表、矩阵、区间问题、栈、链表、二叉树、二叉搜索树、图、回溯、二分查找、堆、贪心算法、动态规划、位运算、数学、多维动态规划等。各板块的数量并不平均,但重点非常突出。
| 板块 | 大致占比 | 重要程度 | 建议投入时间 |
|---|---|---|---|
| 数组与哈希表 | 15%左右 | 必须满分 | 10天左右 |
| 双指针与滑动窗口 | 10%左右 | 必须满分 | 8天左右 |
| 链表与栈 | 10%左右 | 必须满分 | 8天左右 |
| 二叉树与二叉搜索树 | 15%左右 | 必须满分 | 12天左右 |
| 动态规划与多维DP | 20%左右 | 拉开差距的关键 | 15天以上 |
| 回溯算法 | 8%左右 | 高频考点 | 8天左右 |
| 图与拓扑排序 | 8%左右 | 核心但独立 | 8天左右 |
| 二分查找与贪心 | 10%左右 | 高频考点 | 7天左右 |
| 堆、位运算、数学等 | 5%左右 | 补充拿分 | 5天左右 |
这个优先级是我根据自己的复习体验重新排过的,不一定和题单顺序完全一致,但它反映了一个事实:数组、二叉树、动态规划、回溯、双指针和滑动窗口这几类,出现的频率最高,也最值得投入时间。我特别想提醒的是,不要按题单的原始顺序从第1题一路刷到底,而是按专题分组推进。第一周集中刷数组和哈希表,第二周集中刷双指针和滑动窗口,这样更容易形成“类题感”,刷到第三四道同类题时,你已经能看出背后的共同套路了。
2. 第71天进度怎么验证:节奏复盘与三项关键能力
2.1 71天刷150题的进度参考与时间分配
很多人一听“71天刷完150题”就觉得强度很高,其实拆开算一下,平均每天只需要2.1道题。如果每天能保证两个小时,这个进度完全可行。真正难的从来不是单日题量,而是“稳定地持续下去”。
我比较推荐的推进节奏是:基础专题慢启动,重难点专题留足余量,冲刺阶段预留缓冲。具体来说,前期数组和链表这些基础题虽然简单,但我会故意放慢速度,把递归和迭代两种写法都过一遍,把边界条件的思考过程写进注释里,这一步的慢是为了后程的快。到了动态规划和图论这种重难点,我反而不追求一天多刷,一天一到两道,但每一道都会花时间把状态定义、转移过程、代码实现完整走一遍。
如果按这个节奏走,大概的日历会是:第一周到第二周打基础,数组、字符串、哈希表、双指针全部过一遍;第三周到第五周进入数据结构主战场,链表、栈、队列、二叉树、二叉搜索树依次推进;第六周到第七周集中处理回溯和搜索类问题;第八周到第十周是动态规划攻坚期,这也是大多数人真正拉开差距的阶段;第十周以后安排二分、贪心、堆、位运算等补充板块,顺便开始错题重刷和限时模拟。第71天正好处在动态规划攻坚结束、开始冲刺综合复习的位置,这个阶段最典型的特征就是:看到题目不再发怵,但偶尔还是会在细节上翻车。
2.2 刷到中后段必然要跨过的三个坎
我在前面这些天里,遇到过三个特别典型的坎,几乎每个刷到中段的人都会撞上。
第一个坎是动态规划的状态定义。很多DP题一上来就是一堆数字让你求最优解,你很容易被题目表面的形式带偏。我踩过最多的坑就是在状态转移方程上来回试探,一开始定义的状态维度不够,算到一半发现漏了关键信息,只能推翻重来。后来我养成了一个习惯:先不急着写状态转移方程,而是把暴力递归的过程写在纸上,把每一层递归里会变化的参数都列出来,这些参数往往就是状态的原型。比如求编辑距离,递归的参数是两个字符串的下标,那么状态自然就是二维的dp[i][j];再比如打家劫舍,递归的参数是“当前偷到第几个房子”和“上一个房子有没有被偷”,把它简化以后就是dp[i]表示偷到第i个房子时的最大金额。这个从递归到动态规划的推导路径,比直接背状态转移方程靠谱得多。
第二个坎是滑动窗口的收缩逻辑。滑动窗口题看着套路统一,其实细节差异极大。核心是保证窗口在整个遍历过程中始终满足某个条件,右指针负责扩张,左指针负责收缩,真正的难点在于“什么时候收缩”和“收缩到什么程度”。拿最短覆盖子串来说,条件是窗口内必须包含目标字符串的所有字符,所以收缩的时机是“条件已经满足的时候”,要一直缩到刚不满足为止;而最长无重复子串这类题,收缩的时机是“出现了重复字符”,要一直缩到重复消除。这两个场景长得非常像,但收缩逻辑完全不同。我的经验是,做滑动窗口题之前先用一句话写清楚“窗口在什么条件下是合法的”,然后让代码严格围绕这个定义来写,能少踩很多坑。
第三个坎是回溯算法的去重。回溯本身是一个很稳定的模板:终止条件、路径记录、选择、递归、撤销选择。但真正让很多人崩溃的是剪枝和去重,尤其是“同一层不能选重复元素”和“不同层之间可以选相同值”这两个规则,容易绕晕。我自己的解决办法很笨但有效:每次写回溯题,先在代码注释里写清楚两件事——这个变量代表层数还是位置;当前这层递归的去重条件到底是什么。想清楚再动手,写出来的代码基本不会出现重复结果。
2.3 如何判断一道题是真的会了还是只是看过
刷题最怕的就是自我感觉良好,以为看懂了题解就算会了。我给自己定了一个三层的判断标准。
第一层是独立复现:合上题解和所有笔记,在一个空白的编辑器里把这道题从零写出来,能编译能通过,这算“会写”。第二层是变式迁移:把题目换一换条件,比如把数组改成链表、把求最大值改成求方案数,我能不能识别出这是同一道题,并且知道原解法需要做什么修改,这算“会想”。第三层是口头表达:不看代码,用三分钟把这道题的思路、复杂度、边界处理讲清楚,能让一个没做过这道题的人听明白,这算“会讲”。大多数刷题刷到半途觉得“没什么效果”的人,问题都出在只追求第一层,把第二层和第三层完全忽略掉了。第71天这个时间点,正好适合用这三层标准把前半程的题重新过一遍,你会发现很多你曾经以为“刷过”的题,其实根本没有真正掌握。
3. 核心专题拆解:决定面试下限的五个板块
3.1 数组、哈希表、双指针与滑动窗口:最不应该丢分的阵地
数组和哈希表是面试里最基础也最不能丢分的部分。很多数组题看起来变化多端,其实底层套路非常集中:排序加双指针能解决一大批问题,比如三数之和、四数之和、颜色分类;哈希表的核心用法是拿空间换时间,把查找时间从O(n)降到O(1),两数之和是这类题的原型。
这里特别想说的是双指针。双指针其实分两种,一种是相向而行,左指针从头往尾走、右指针从尾往头走,它们相遇时就结束了,这类题常见于有序数组、字符串反转、盛最多水的容器;另一种是同向而行,也就是常说的快慢指针,常见于链表求中点、判断链表是否有环、删除倒数第N个节点。这两种双指针解决的是完全不同的问题,但它们的共同点是都利用了“指针移动一次的信息量”来避免重复遍历。
滑动窗口是双指针的进阶形态,我前文说过它的核心是窗口合法性的定义。它的通用框架是:右指针不断向前,把新元素纳入窗口;窗口不满足条件时,左指针不断收缩;在合适的时机记录一个候选答案。这里的时机选择很容易出错,有的题要求在收缩前记录,有的题要求收缩后记录,做之前一定要想清楚。以最长无重复子串为例,答案是在收缩完成、窗口重新合法时记录的;而以长度最小的子数组为例,答案是在收缩过程中记录窗口长度的。这两者只差一行代码的位置,却会带来完全不同的结果。
3.2 链表、栈与队列:边界条件和哨兵技巧的练兵场
链表题在150题里的绝对数量不算多,但几乎每场面试都有可能出现。它的难度不在于思路,而在于代码实现时的边界细节。链表操作最重要的一个问题是:操作者必须时刻知道“当前节点的前驱是谁”,否则非常容易断链、漏链、甚至把链表搞成循环。反转链表、删除节点、合并两个有序链表这些题,每次写之前我都建议先在纸上画出节点指向关系,再把代码写出来。
关于链表的边界处理,我强烈建议使用哨兵节点。所谓哨兵节点,就是在真正头结点之前加一个不存有效值的辅助节点,用来统一处理“头结点被修改”的情况。比如删除链表的倒数第N个节点、删除排序链表中的重复元素,这些题如果没有哨兵节点,就会写出一堆if判断“当前节点是不是头结点”,加上哨兵以后逻辑会简洁很多。快慢指针也是链表题的高频套路,判断有环、找环入口、找链表中点,本质都是用一次遍历代替两次遍历。
栈和队列在面试经典150题里的出现方式也很有规律。栈更多用于“最近相关性”问题,典型场景是括号匹配、有效的括号、表达式求值、字符串解码。单调栈是一个必须掌握的变体,专门用来找“下一个比当前更大或更小的元素”,它的模板是:遍历每个元素,当栈顶元素被当前元素破坏了单调性时,就弹出栈顶并记录答案,最后把当前元素入栈。因为这个操作让每个元素最多进出栈一次,整体时间复杂度是O(n)。优先队列其实就是堆的包装类,面试里的高频用法是合并K个有序链表、前K个高频元素、滑动窗口最大值,这三道题只要掌握堆就够了,不需要了解堆的底层实现细节。
3.3 二叉树与图:把递归想透,剩下的就是模板
二叉树是面试必考区,也是很多人刷题时最容易“看得懂、写不对”的板块。二叉树题目的核心是递归,而递归的核心思维是:假设左子树和右子树都已经处理好了,当前节点只需要把子问题的结果拼接起来。比如求最大深度,就是max(左子树深度, 右子树深度) + 1;判断两棵树是否相同,就是当前节点值相等,并且左子树相同、右子树相同;判断是否是对称二叉树,则是把root.left和root.right当成两棵树来比较。
递归写不好的根本原因,是对“递归的输入是什么、输出是什么、终止条件是什么”这三件事没有想清楚。我刷二叉树题有一段时间陷入瓶颈,后来养成一个习惯,每次写递归函数前,先在注释里写三行:这个函数接收什么参数、返回什么、终止条件是什么。三行注释写清楚以后,递归体基本上就能顺理成章地写出来。层序遍历是二叉树的另一个高频考点,用队列做BFS,模板是“每层先记录当前队列长度,再弹出这一层所有节点,把下一层节点入队”,这个模板延伸到图论里,就是求最短路径步数的基础。
二叉搜索树有一些特殊的性质需要利用,最核心的一条是中序遍历结果是升序的。很多题只要在中序遍历过程中做点文章就能解出来,比如验证二叉搜索树、二叉搜索树中第K小的元素、把二叉搜索树转换为累加树。图的题目在150题里占比不大,但基本个个都是重点。我建议掌握四件事:用邻接表建图、DFS和BFS两种遍历、拓扑排序判断有向图是否有环、并查集判断无向图的连通分量。岛屿数量、课程表、腐烂的橘子这些经典题,只要吃透模板,基本都能套上。
3.4 回溯、贪心与二分:模板化最强的三个板块
回溯算法的模板化程度非常高,基本框架就是五步:判断终止条件;把当前路径记录到结果;遍历候选集合;做选择;递归并在返回后撤销选择。全排列、组合、子集、括号生成、N皇后、单词搜索,都能套进这个框架。一个很好用的判断方法:如果这个题需要你枚举出所有可能的方案,基本就往回溯上想。
回溯真正拉开差距的是剪枝。最常见的两种剪枝:一是根据剩余候选元素的数量判断当前路径还有没有可能凑够目标长度,不够就直接返回;二是对候选集合先排序,在同一层递归中跳过值相同的元素,这是最常用的去重手段。拿组合总和II来说,如果没有这个同层去重,结果里就会出现一堆重复组合。贪心算法在150题里承担的角色比较微妙,它看起来简单,但很容易让人误判。贪心的核心不是“每一步选择当前看起来最好的”,而是“每一步的局部最优能推导出全局最优”。面试里常见的贪心场景包括区间调度、跳跃游戏、分发饼干、加油站、买卖股票等。这些题只背结论也能过,但变式题一旦换了个包装,你就很难判断能不能贪心,所以最好还是花点时间理解背后的直觉。
二分查找是“看着简单,写着容易错”的典型板块。99%的二分bug都出在“区间不变式”上——你定义的左指针和右指针到底是闭区间还是开区间,决定了循环条件怎么写、指针怎么更新。我个人的习惯是统一用左闭右开区间,即l指向第一个可行位置,r指向第一个不可行位置,循环条件是l < r,收缩时l = mid + 1或r = mid。这个习惯一旦固定,写普通二分查找、搜索插入位置、寻找旋转排序数组中的最小值,都能直接套用。还有一类二分是在值域上做而不是在数组下标上做,比如求“最大值最小化”和“最小值最大化”,在机器人能吃多少香蕉、分割数组的最大值这类题里特别常见,核心是先写一个check(mid)函数判断可行性,再用二分缩小范围。
3.5 动态规划:如何从送命题练成送分题
动态规划是150题里难度最集中的板块,也是所有面试者绕不开的关口。我的学习路径非常建议参考:先别急着背状态转移方程,而是把题目先还原成一个暴力递归问题,用最朴素的搜索思路写一个能跑但很可能超时的版本,然后加上记忆化缓存,把递归树中重复计算的节点直接缓存起来。这一步能跑通之后,再把它改写成自底向上的迭代版本。这个“递归到记忆化再到迭代”的过程,能帮你真正理解dp数组的下标代表什么、遍历顺序为什么重要、初始化条件为什么长那样。
具体到场景,线性DP是最基础的,典型题是打家劫舍、爬楼梯、最长递增子序列;二维DP的典型代表是不同路径、最长公共子序列、编辑距离,几乎全是“把两个序列的尾部放一起比较”的思考方式;背包问题的核心在0-1和完全两种类型之间,0-1背包的容量要倒序遍历,完全背包要正序遍历,顺序写反代码依然能通过一部分用例,但答案就是错的,而且极难排查;区间DP以最长回文子串为代表,思路是小区间推导大区间;状态压缩DP在150题里的出现概率不高,但旅行商问题简化版这类题可以当作思维扩展。
关于DP的初始化,它真的是重灾区。dp[i][j]在迭代之前,dp[0][0]或者第一行第一列到底等于多少,直接决定结果对不对。我的习惯是,每次写完状态转移方程,立刻用一个最小规模的输入手动跑一遍,用debugger或者打印输出看dp数组的填充过程。这一步看起来不起眼,但能避免大量因为初始化错误而浪费的时间。
4. 让刷题形成复利:方法、工具与时间管理
4.1 三遍法:第一遍AC,第二遍精读,第三遍复现
如果只是按顺序一路刷过去,刷完150道,回头会发现大部分都忘得差不多了,这是非常正常的。没有反复巩固的刷题,本质上是在做无用功。我的做法是把每道题分三遍过。
第一遍是“独立AC”:拿到题目先自己想,给自己15到30分钟,想不出来就看题解,看完题解必须合上,自己把代码独立写一遍,能通过全部用例才算完成。第二遍是“隔天复写”:隔一天或两天,在不看任何资料的情况下重新做这道题,这一遍的重点不是AC,而是检查自己能不能写出完整可运行的代码,并且说清楚时间复杂度和空间复杂度。第三遍是“一周复现”:一周后把题目拿出来快速过一遍,只要求能快速写出核心逻辑,不要求每个细节都背下来。三遍不一定要整轮做完再进入下一题,可以滚动进行,比如今天做新题,明天重做今天做的,下周抽查本周的几道经典题。这套流程看上去花的时间翻了三倍,但记忆留存率比一遍刷完高很多。
4.2 建立模式识别卡,让题目在脑子里自动归类
刷题到中后段,最重要的能力是条件反射。看到“最长无重复子串”,应该想到滑动窗口加哈希表;看到“寻找两个有序数组的中位数”,应该想到二分查找;看到“接雨水”,应该想到单调栈或双指针;看到“岛屿数量”,应该想到深度优先搜索;看到“课程表”,应该想到拓扑排序。
我建议准备一个文档,每做完一类题,就写一行“问题特征加解题框架”,不要复制题目原文,用自己的话压缩成十几个字。这个文档就是你的专属模式识别卡,面试前翻一遍,比重新刷一遍题更有效率。我自己的卡片里有很多这样的条目,比如“有序数组加找目标:优先二分”“求所有子集:回溯加排序去重”“连通块数量:DFS加visited数组”“环检测:快慢指针或拓扑排序度数法”“最值问题:先想DP再想贪心”。这种把题目抽象成几行字的过程,会让你的脑内模板库越来越清晰,遇到新题的时候,模板库越全,你能归类得越快。
4.3 把刷题当成项目来管理,而不是随缘发力
刷题想长期坚持,靠的绝不是意志力,而是把这件事拆解成可以执行的最小单位。我会把每日时间固定下来:早上用30分钟快速回看昨天做过的题,不重写代码,只在脑子里过一遍思路,想不起来的地方做上标记;晚上用一个半到两个小时做新题,中间不刷手机、不切页面。
做题时给每一题设置一个时间上限。如果一道中等难度的题想了40分钟还没有任何像样的思路,我会直接看题解,第二天再做一次复盘,重点想一个问题:“我当时为什么没想到这个方向?”这个复盘的价值在于,大多数时候你不是不会,而是没有识别出题目背后的模式。除了每日节奏,每周还要做一个错题回顾,把一周之内没能独立AC的题重新做一遍。这样可以保证整个计划不会变成“每天看起来很忙,实际上进步很少”的假勤奋。
4.4 从屏幕到白板:练口述就是在练面试
面试时不是一个人对着屏幕闷头写代码,而是要边写边说。很多刷题很多的人,到了面试现场却表达不清,就是因为平时从来没有练过“讲题”。我的建议是,每做完一道题,用不超过三分钟的时间,把五句话说清楚:题目要求是什么;如果暴力做,思路是什么;暴力思路的复杂度是多少;我为什么选择了这个优化方案;优化后复杂度是多少。
这个练习一开始会觉得很别扭,嘴跟不上脑子的感觉非常明显,但坚持到第30题左右,你会发现表达越来越顺。我给一个一起刷题的朋友的建议是,把自己讲题的过程录音下来,回放时你会发现自己说的很多话其实逻辑是不连贯的,比如“这个指针要动一下”但没说清楚往哪动、为什么动。这种口述练习是在为面试做最直接的准备,因为它逼着你在没有代码反馈的情况下把思路用语言组织清楚。
5. 刷题路上的典型问题与排查经验
5.1 能看懂题解,但自己一写就卡住
这个问题几乎每个人都会遇到,原因通常是你对题解的理解停留在“逻辑上明白了”,还没有落到“代码细节上”。比如看完动态规划的题解,你知道状态转移方程长什么样,但初始化到底怎么写、循环从哪开始到哪结束、需不需要额外开一个虚拟节点,这些细节才是真正决定你能否AC的地方。
我的修正办法是:看完题解之后不马上写代码,先把题解合上,在纸上写出三个东西——状态定义、状态转移方程、初始化条件;写不出来就说明有一环还没理解,回头再看;写出来了,再对着这三行内容独立写完整代码。这个过程其实就是把“被动看懂”转化成“主动重建”。我试过很多次,只要这一步做扎实,后面重写时基本不会卡壳。
5.2 死磕难题还是先跳过
刷题过程中很容易陷入一种执念:一道题不AC就不睡觉。这种心态很危险,因为一道题卡住三四个小时,不仅挤占了其他题目的时间,还会严重打击信心。我给自己定的原则是:如果一个题目想了40分钟没有至少一个可以尝试的思路,就果断跳过,把题目和我的思路碎片记进错题本,过两周再回来看。
跳过的前提是你确实尽力了,而不是遇到不会就立刻看题解。很多当时看不懂的中等偏难题,其实是因为你缺少前置知识,等你把相关专题刷完,再回头看这道题,经常会有“原来它考的是这个东西”的顿悟感。反过来,如果你发现简单题也总是想复杂,那就要提醒自己先看数据范围:数组长度只有几百,暴力枚举大概率就是正解;数组长度到10的5次方,才需要考虑O(n log n)甚至O(n)的算法。看到题先问数据范围,这个习惯能帮你节省大量不必要的“过度思考”。
5.3 刷完150题还是心里没底
刷题数量到了,心里依然没底,问题多半出在“输出”不够。刷题是输入,面试是输出,这两者之间有巨大的鸿沟。刷题时你可以沉默地写代码,但面试时你需要边说边写,并且要应对面试官随时抛出的追问。我的补救方法非常直接:做高强度的口述练习。
练习方式是给自己随机抽一道做过的题,限时10分钟,不写代码只讲思路,讲完以后再快速写出代码骨架。这个训练最直接的效果是逼着你在不依赖代码的情况下组织语言。多练几次以后,你会发现不仅表达能力变强了,对题目的理解也更深入了。另外还想说一句,面试时遇到没见过的新题完全正常,但如果你脑内的模板库足够全,新题大概率是旧题型的组合或变种,你能更快地找到切入点。
5.4 被测试用例折磨的深夜
写代码时,很多人习惯跑完题目自带的示例然后直接就提交,直到被某个隐藏用例击穿才回过神来。被测试用例折磨的次数多了,我养成了一个习惯:每道题的代码写完之后,先跑示例用例,再自己构造几组极端边界用例跑一遍,最后才提交。
边界用例要有的放矢。数组题要测空数组、只有一个元素、全是相同元素、严格递增、严格递减、包含负数、可能溢出的大整数;链表题要测只有一个节点、删除头结点、删除尾节点、链表为空;二叉树题要测空树、只有左子树、只有右子树、深度很大的树、所有节点值相同;滑动窗口题要测窗口长度大于数组长度、窗口长度等于数组长度。自己构造用例的过程,其实就是换个角度重新理解题目的过程。你会发现很多你以为是AC了的题,其实只是恰好样例没有暴露问题。
6. 从150题到面试现场
6.1 把做题能力转换成面试表达力
刷题刷到后半程,不能只满足于“能AC”,还要能把每一步决策讲成一条完整的逻辑线。我在模拟面试时固定使用一个叙述顺序,感觉效果很好:先说明自己理解了题意,复述题目的关键限制,举一个小规模输入输出作为例子;然后说“如果暴力做,可以怎么做”,并给出暴力做法的时间复杂度;接着指出这个方案的瓶颈在哪里,顺势引入自己的优化思路;最后给出代码结构的概括,并口算复杂度。
这套顺序覆盖了面试官大部分追问的路径。你会发现,当你按照这条线讲题时,面试官很少打断你,因为这个叙述天然符合人类理解问题的逻辑:从最朴素的想法出发,逐步逼近最优解。它也能帮你应对“你还有没有更好的解法”这类问题,因为你已经把暴力解和优化解放在一起对比过,思路是连贯的。
6.2 第71天之后的扩展方向
现在正好是第71天,我给自己定的下一步不是盲目接着往后做,而是做一轮“收敛式复习”:第一步把所有错题重新做一遍,那些隔天不能独立AC的题是重点;第二步选出三个最不熟悉的专题,每个专题额外找几道同类型的题目强化训练;第三步做几套限时综合模拟,把时间压力和选题策略重新校准。150题本身不是终点,它的意义在于帮你把地基打牢。地基稳了以后,再去看其他来源的题目,或者自己在题库里找题练手,都会比一开始盲目刷题高效得多。
6.3 打卡第71天的真实感受
坚持到第71天,我最深的体会是:刷题这件事,拉开学霸和普通人之间差距的往往不是天赋,而是“能不能稳定地持续下去”。每天记录一行打卡:日期、题目编号、用时、是否一次通过、一句话总结,这个看起来微不足道的动作,其实是最好的项目管理。它让进度变得可见,也让偷懒变得非常明显——如果你连续三天没有记录,你很快就知道计划失控了。
如果你也想对自己的题目水平有个底气,与其纠结“一天必须刷几题”,不如先守住一条底线:今天能不能把一道题彻底搞懂、并且明天还能独立复现出来。稳定地做到这一步,150题就不再是一个遥远的目标,而是一个每天都能往前推进一点的过程。等你在第71天回头看的时候,你会发现自己已经不是最初那个见了链表就头疼的人了。