拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

力扣刷题26天112题:三遍法高效刷题计划与面试实战

力扣刷题26天112题:三遍法高效刷题计划与面试实战

力扣刷题这件事,我见过太多人陷入同一种循环:第一天热血沸腾,打开力扣从第一题开刷,刷到第五题发现"两数之和"看着眼熟,但脑子里只有暴力解,于是翻题解、点收藏、退出页面,下一次打开可能是两周后。我也曾经是其中一员,直到给自己定了一个非常具体的指标——26天刷完112题,平均每天4.3题,把所有高频题型完整过一遍。这个计划我管它叫"力扣日刷26112"。说实话,一开始我只是想逼自己一把,没想到真正跑完26天后,收获比想象中大得多:不是背下了多少题,而是形成了一套能稳定复用的刷题节奏。这篇文章没有任何玄学,就是把这份计划的设计逻辑、刷题方法、踩过的坑和最后验收的工具全部摊开。适合准备实习秋招但时间紧的人,也适合刷到怀疑人生、想重新找回节奏的中间态选手。

1. 为什么是26天112题:先把计划算成一道数学题

很多刷题计划失败,根子不在意志力,而在计划本身拍脑袋。今天心情好多刷几道,明天累了就跳过,最后一周过去打开记录一看,有效刷题量可能不到五道。我这次下决心之前先做了一道简单的算术题,把"每天该做多少"这件事彻底量化。

1.1 这组数字是怎么来的

先定周期。26天约等于一个月,不长不短,既能覆盖一遍完整的题型遍历,又刚好卡在遗忘曲线发挥作用的时间窗口:一道题在第2天、第7天复习,到第26天基本已经进入长期记忆。更重要的是,一个月是人能够靠"新鲜感+紧迫感"坚持下来的合理上限,再长就需要额外的意志力来维持。

再算题量。我翻了力扣上近几年面试出题频率较高的标签,把题型归成十类左右,每一类按面试概率分配题数,加起来大约是100道,再预留12道作为机动余量,正好凑成112道。均摊到26天就是每天4.3道,取整为4道,状态好的日子多做1到2道,状态差的日子至少保住底数。这个强度是我反复算过的:一道全新中等题,从读题到AC一般要30到40分钟,复习一道旧题15到20分钟,每天固定掏出90分钟就能跑完,不会把上班和休息彻底挤没。

1.2 112道题的题型分配表

分配比例直接决定你刷完一遍之后的能力结构。我按自己当时的薄弱环节和面试频率做了下面这张表,实测到最后一天并没有出现"某个题型完全没碰过"的情况:

题型分类题数备注
数组与双指针18基础中的基础,很多中等题都是从这里延伸的
二叉树与递归18面试高频,必须形成肌肉记忆
动态规划16先学套路,不追求难题,重点在状态定义
哈希表12空间换时间的典型场景
链表10注意指针操作的细节
DFS与BFS8与二叉树递归部分重叠,加深应用
回溯算法8模板化最明显的题型,性价比很高
栈与队列8单调栈是重点,很多中等题的关键
二分查找6掌握开闭区间写法后可覆盖大部分变体
贪心算法4和单调栈配合,好入门但需多练
图论与并查集4只学了最基础的代表题

总计112道。这个比例并不神秘,核心思路就一句话:按面试频率分配做题时间,而不是按个人喜好分配。我见过很多朋友天天刷链表题,遇到动态规划就跳过,结果面试时连着被问两道树题直接懵掉。

1.3 "刷完一道题"的完成标准

计划开始的第一天,我就给自己立了一条死规则:一道题只有同时满足三个条件——独立写出代码并通过全部测试用例、能口述解题思路、能说清时间空间复杂度——才算真正"刷完"。看题解照着敲一遍不算,半年前收藏过不算,讨论区看到过解法也不算。

这条规则最大的作用是防止"自我感动式刷题"。很多人记录里写着刷了300道,实际遇到新题还是没思路,就是因为在"看懂答案"和"会做题"之间画了等号。我把标准定严之后,前面的题虽然刷得慢,但每道题留下的东西都是实的,越到后面复习成本越低。

2. "三遍法"的刷题节奏:隔天重写才是重点

计划定了题量之后,紧接着就得解决一个更实际的问题:怎么刷才能保证不白刷。我采用的是"三遍法",也就是一道题在26天周期内至少碰三遍,分别在第一遍、隔天、一周后执行。这个方法不稀奇,但绝大多数人只做了第一遍。

2.1 第一遍:45分钟内的完整闭环

第一遍的目标不是"做出难题",而是建立完整的解题闭环。具体流程我固定成这样:

  1. 读题后给自己5分钟想思路,这5分钟内不准翻题解、不准看讨论区,只在草稿纸上写伪代码。
  2. 有思路就直接上手写,给自己20分钟完成第一版代码。
  3. 测试和调试再留15到20分钟,直到通过全部用例。

如果5分钟没有思路,或者20分钟代码写不出来,我的做法是果断看题解。注意,看题解不是看完就完,而是合上题解,凭记忆和理解重新敲一遍,敲不出来就再看,直到能独立AC为止。这一步最大的意义是把自己"卡住的位置"暴露出来,为后面复习留下靶子。

2.2 第二遍:隔天"仰写"是真正的分水岭

第二遍发生在第二天,规则更严格:不翻题解、不看自己第一遍的提交记录,甚至不打开讨论区,用一张白纸和编辑器直接重写这道题。我管它叫"仰写",意思是像默写古诗一样把代码默出来。

这一遍是整套方法里价值最高的60%。原因很简单:第一遍结束的时候,你对题目的理解还停留在"顺着题解的思路走了一遍",大脑里残留着刚刚的记忆,AC可能只是短期记忆的复现。等到第二天,短期记忆消退了大半,你要是还能不看任何资料做出来,才说明解题思路真正归你了。

我自己的数据是:第一天刷的4道题里,第二天能完全独立重写的只有2到3道。剩下那1到2道就立刻进入"错题本"名单,安排在第7天再做一遍。没有这一遍的话,刷题就是在给自己表演"我看懂了"。

2.3 第三遍:一周后限时重写加讲题

第三遍放在第7天,形式直接模拟面试:限时20分钟,用编辑器写,不写伪代码直接写完整解法,AC之后再花2分钟把思路顺一遍。如果这轮还能顺利通过,这道题才算从短期记忆变成了长期记忆。

讲题这一步很多人忽略,我觉得它比代码本身更重要。能AC但讲不清楚,说明你对这道题的认知还是局部操作性的,没有抽象成方法。我会在AC之后用一句话概括"这题考的是什么、核心思路是什么",比如"这题就是双指针把有序数组原地去重,slow指针维护结果数组的尾部"。能说出这种层面的话,遇到同类题就不会慌。

2.4 错题记录:只记卡点,不抄题解

我的错题本不抄完整题解,只记四样东西:题号、卡在哪里、当前解法的核心思路、一句话总结。举例两条真实记录:

  • 题号509:卡点是"dp[0]和dp[1]的初始值没想清楚就急着写出状态转移方程"。总结:写DP前先问自己两个问题——dp[i]代表什么,i等于0和1时是多少。
  • 题号206:明明会迭代法,却一直纠结递归写法怎么写,浪费了10分钟。总结:先写出最稳的方法,再谈优化,不要在写码阶段反复换思路。

这种记录方式最大的好处是复习时非常高效,一分钟过一条,重点全在"我上次为什么错"上,而不是重新看一遍解法。

3. 从第26题到第112题:两道招牌题的完整拆解

标题里的"26112",另一个巧合同样值得展开说:我在这个计划里遇到的第一道关键题是力扣第26题,最后几天反复研究的招牌题之一是第112题。这两道题一个简单一个中等,但都很有代表性,高频、易变形,而且都能作为一类题型的母题来用。

3.1 第26题:删除有序数组中的重复项(双指针原地修改)

题目要求是原地删除有序数组中的重复元素,让每个元素最多出现一次,返回新数组的长度。核心限制是"原地",也就是不能用额外数组,这直接排除了暴力解法。最标准的解法是快慢双指针:

class Solution: def removeDuplicates(self, nums: List[int]) -> int: if not nums: return 0 slow = 1 for fast in range(1, len(nums)): if nums[fast] != nums[fast - 1]: nums[slow] = nums[fast] slow += 1 return slow

这里的核心逻辑是:slow指针始终指向"下一个不重复元素应该放的位置",fast指针负责扫描整个数组。只要发现fast位置的元素和前一个元素不同,就说明遇到了新元素,把它放到slow位置,然后slow前进。由于数组本身就是有序的,所以只需要和前一个元素比较,不需要额外哈希表。

这类题的易错点主要有两个。第一是边界:数组为空时要单独处理;第二是理解"原地去重"结果数组的语义:返回值是长度,但真正起作用的是把不重复元素挪到数组前段。很多人在面试时能写出代码,却说不清slow指针的含义,这就会给面试官留下"背题"的印象。

3.2 第112题:路径总和(二叉树递归)

第112题问的是一棵二叉树里是否存在"从根节点到叶子节点"的路径,让路径上所有节点值之和等于给定的targetSum。这是我计划后期反复拿出来琢磨的一道题,因为它看似基础,但递归设计得很典型:

class Solution: def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool: if not root: return False if not root.left and not root.right: return root.val == targetSum return self.hasPathSum(root.left, targetSum - root.val) or self.hasPathSum(root.right, targetSum - root.val)

这道题最容易踩的坑是"返回值设计"。很多人第一反应是让递归函数返回"剩余路径的和",但更自然的做法是维护一个逐渐减小的targetSum:每向下走一层,就把根节点的值从targetSum里减掉,到了叶子节点直接判断减到零没有。

另一个坑是"空节点"和"叶子节点"不能混为一谈。比如根节点只有一个左孩子、左孩子是叶子时,如果只判断not root: return targetSum == 0这种写法,会在空指针处错误地返回结果。必须让递归在叶子节点处停止,而不是在空节点处收尾。这个细节我见过不少人栽过跟头。

3.3 一题带一类:怎么把单题刷成题组

刷题效率高的秘诀不在于刷得多,而在于主动建立"题组"意识。我刷第26题的时候,会顺手把它和"移动零""三数之和"放在一起,归纳成"数组原地操作+指针移动"这一类;刷第112题的时候,会把它和"路径总和II""二叉树的所有路径""根到叶的数字"放成一类,称为"根到叶路径递归"。

每道题刷完,我都会问自己三个问题:这道题属于哪个题型模板?它的核心变量是什么?如果我改一下条件,能不能变成另一道题?比如第26题把"有序数组"改成"无序数组",解法就完全变了;第112题把"存在性判断"改成"返回所有路径",就从DFS递归变成了回溯。

这种迁移练习最大的价值是:刷一道题,相当于覆盖了三四道同类题。112道的题量,实际上让我攒下的小题型模板大约有30组,后面遇到新题时基本都能快速归类,解题速度明显提升。

4. 碎片时间、瓶颈期与"低电量模式":支撑26天的三个保底手段

计划能不能跑完,前7天靠决心,后19天全靠机制。这一章我把26天里真正保命的几个手段记下来,特别适合非全职刷题、还要上班上学的人参考。

4.1 每天90分钟怎么切:新题为主,复习为辅

我每天的时间预算精确到分钟:30分钟用于复习昨天的遗留题和错题,60分钟用于两道新题。早上一段通勤时间大约20分钟,用来做一道简单题热身;午休30分钟做一道中等题;晚上找一个完整的45分钟,先复盘白天卡住的题,再刷一道当天计划中的新题。

一天四道的具体分配我按"两新两旧"来排:第一道是昨天的遗留题,第二道是错题本复习,第三道和第四道是今天的新题。这样每天既有推进,又有巩固,不会出现"刷到一半忘了前面的题"的情况。哪怕某天实在挤不出完整时间,我也会至少保住那道复习题,因为复习题20分钟内就能完成,而它恰恰是最容易产生效果的部分。

4.2 瓶颈期怎么办:先把"量"降下来

第11天左右我进入了一个明显的瓶颈期:连续三天新题AC率不到一半,很多题看一眼觉得熟悉,动手写就卡壳。那几天晚上我躺在床上翻记录,发现自己白天刷的题虽然数量达标了,但晚上复盘时根本想不起思路。

我采取了一个差点救了这个计划的操作:主动降量。连续两天执行"低电量模式"——每天只做一道新题,而且允许自己看题解,看完只写思路总结,不强行AC。这听起来像偷懒,实际作用是让大脑从"必须做出来"的压力里抽身,重新建立做题的松弛感。两天之后我再恢复正常节奏,状态明显回来了。

4.3 从"能AC"到"跑赢90%":提交后必看时间和内存

另一个贯穿全程的习惯是:每次AC之后,不要立刻划到下一题,先看一眼提交记录里的执行时间排名和内存占用。力扣提交后会给一个击败百分比,这其实是非常高效的自测反馈。

比如第26题我第一次提交只击败了30%,虽然AC了,但说明写法还有优化空间。我把nums[fast] != nums[fast - 1]的写法改了下,从每次比较改为记录上一个值,排名就到了90%以上。动态规划题也一样,二维数组能压缩成一维数组的时候,空间复杂度就从O(n²)降到了O(n)。养成"AC只是及格线"的习惯后,你的代码质量会随着刷题量一起涨,而不是只有量在涨。

5. 26天之后:我的验收清单与面试答题框架

第25天到第26天我没有刷新题,只做验收。这一步太重要了,如果不验收,你根本不知道这112道题到底在你脑子里留下了多少,而验收结果会直接告诉你哪些地方需要返工。

5.1 三栏复盘表:题号、核心思路、复杂度

我在最后两天把112道题全部重览了一遍,用一张三栏表记录每一道题的核心信息:

题号核心思路时空复杂度
26快慢指针原地去重O(n) / O(1)
112递归递减targetSum,叶子节点判断O(n) / O(height)
509斐波那契DP,一维数组滚动优化O(n) / O(1)
206三指针翻转链表O(n) / O(1)

规则很简单:能在一句话内报出核心思路和复杂度的题,直接划掉;想了半天才想起来,或者思路根本说不清的题,标记成"待重刷"。我最后标出来约17道待重刷题,主要集中在动态规划中等题和图论基础题上。标记之后我又花了两天时间把这几道题按第三遍的标准重新过了一遍。

5.2 "讲题测试":两分钟内说清一道题

验收的第二个环节是讲题。我随机从列表中抽题,用手机录音,每道题给自己两分钟:先说题目要求,再说思路,最后说复杂度。说完回放录音,只要中间出现超过10秒的停顿,或者思路讲得前后矛盾,这道题就自动进入待重刷名单。

这个测试比写代码更狠,因为它要求你把"会做"变成"会讲"。我实际测下来发现,很多我以为掌握得很好的题,一开口就露馅,比如"这题用栈……不对,是用双端队列……",说明本质上还是记混了。讲题法逼着我把每一道题的内在逻辑重新理了一遍,效果比再看一遍题解强得多。

5.3 现场答题框架:先确认边界,再谈思路

刷完112题之后,我给自己整理出一套在任何笔试面试现场都能直接用的答题框架,四个步骤:

  1. 读题后先问边界和数据范围:数组长度是10以内还是10⁵?数值范围有没有负数和零?树是否可能为空?这些直接决定能用什么复杂度的算法。
  2. 选定数据结构:看到"有序+去重"想到双指针,看到"路径和"想到递归或回溯,看到"最近"想到栈。
  3. 说时间空间复杂度再动手:面试时先报复杂度再写码,面试官会觉得你脑子里有全局观。
  4. 写完用极端用例自测:空数组、长度为1、全是重复元素、树只有左子树——每个框架都有对应的典型边界用例。

这套动作帮我克服了以前"拿到题就闷头写,写到一半发现思路错了"的大问题。真实面试中,哪怕思路不是最优解,只要边界考虑完整、复杂度说得清,面试官通常也愿意引导而不是直接否决。


26天112题刷完,我最真实的感受是:它最大的价值不是让我在面试时多背下了几十道题,而是让我戒掉了"划走式刷题"。以前打开力扣是"刷几道算几道,全凭感觉",现在是"计划里有明确的类型覆盖,每一道题都算数"。最后再分享一个小技巧:把每天刷题打卡和睡前5分钟回顾绑定在一起,睡前只问自己三个问题——今天这题卡在哪、能不能不看题解做出来、它和之前哪道题是一类。这三个问题问完,基本就知道今天的题是真会了还是假会了。这个习惯我到现在还在坚持,效果比早上起来定计划打鸡血强太多。

返回列表