
2026年3月10号到12号我在刷题平台上留下了一份记录。ID是hetao1733837三天时间13道题11次通过覆盖二分、双指针、动态规划、图论和几道模拟题。单独看这份记录成绩不算特别亮眼但把做题顺序和错题复盘拉出来里面的信息量还挺大。这三天并不是临时起意刷着玩而是一场有明确目标的集中训练把几个一直模糊的知识点彻底搞清楚。如果你也在刷题、笔试前突击或者准备面试中的算法环节这份记录里提到的思路、模板和踩坑方式可以拿来直接用。尤其是边界问题和状态定义这两个点几乎每三道题就会遇上一次。下面按我的复盘顺序来写不会按日期流水账而是按知识点和问题来整理。这样比单纯贴AC记录更有参考价值。1. 三天刷题计划是怎么排出来的1.1 为什么是三天而不是一个晚上算法学习有一个“输入—练习—复盘”的循环。一个晚上刷题往往刚进入状态就结束了根本没时间重复。刷题一段时间的提升不是靠“做新题”而是靠“隔一段时间回头再看错题”。三天正好能让这个循环发生两次第一天学的第二天晚上巩固第三天上午再复习一遍。一天或两天的安排很难覆盖超过两个知识点。三天时间我可以安排三块不同的内容同时在每个块内预留容错空间某一类题当天没弄懂晚上可以再找一个同类题强化。如果是临时突击这种容错很重要。一旦卡住不会把整个计划拖垮。很多刚开始刷题的人会给自己排“每天30题”的计划。实际上高强度刷题之后第二天脑子是蒙的前一天的思路记不清更别说总结。三天里我定的目标是每天4到5道有质量的题外加一道随机巩固题。这样总量大概13到16道属于中等偏上强度但每道题都有时间思考、写代码和对着出错记录总结。1.2 按题型分类而不是按难度刷一个经常出现的误区按平台的难度标签从简单到难挨个做。这种做法不是不行但见效慢。原因是不同知识点混在一起大脑还没来得及形成“这类题的套路”又被下一个知识点打断。集中刷同类题型可以在短时间内积累模式识别。这次的安排按知识块分第一天是二分和双指针第二天是动态规划第三天是图论加复盘。每个知识块内部再按难度分层先做基础模板题再做需要变形的题目。比如二分先复习标准的二分查找接着做二分答案的题最后做和双指针结合的题目。同一个主题下的不同场景反复出现解题模板才能真正进入长期记忆而不是看完解析之后“好像懂了”。选这三个主题是有原因的。二分和双指针考察的是区间思维DP考察状态设计图论考察建图能力和遍历策略。这三个方向覆盖了很多常见笔试中的高频点前缀和、最值、连通性、最短路径。把它们放在三天里每天都有新鲜感又不会太散。1.3 每日节奏和时间块安排三天时间不是一个整天扎在电脑前。我按照工作时间表来模拟上午9点到11点第一轮刷题下午2点到4点第二轮刷题或补题晚上8点到9点半只做复盘和整理模板。每轮约40到50分钟中间一定休息10分钟。长时间盯着屏幕容易让思路僵住我试过连续两小时硬刚一道题最后发现是题目理解错了白白浪费一小时。这样安排还有一个原因笔试或实际工作里很少有人让你无限时思考。固定的时间块能训练做题时的紧迫感。如果一道题超过30分钟没有进展我的处理方式是先写下当前思路和疑点标记为“回头再看”换一道题。这不是放弃而是防止情绪消耗。回头再看的时候经常一两分钟就能发现卡点。三天的记录里有两道题都是第一天没AC第二天补上的它们并不是不会而是当时进入了一个死胡同。2. 这三天重点啃的数据结构与模板2.1 二分答案边界问题永远是第一道坎二分这个知识点几乎所有刷题的人都能写出基本的while循环但一遇到“最小化最大值”“最大化最小值”就蒙。原因在于普通二分是对一个排好序的数组找一个目标值而二分答案是对“答案可能的取值范围”做二分再用一个check函数去判断取某个值时是否可行。我这次把二分答案的模板钉死成了下面这样def check(mid): # 判断当前 mid 作为答案是否可行 # 可行返回 True不可行返回 False return ... l, r low, high while l r: mid (l r 1) // 2 if check(mid): l mid # 当前 mid 可行尝试更大 else: r mid - 1 print(l)这个模板针对的是“可行域在右侧要求最大值”的情况所以mid取上中位数(l r 1) // 2。如果题目要求最小值通常是这样while l r: mid (l r) // 2 if check(mid): r mid else: l mid 1这两个模板看起来只差一个1但用错就会死循环。为什么会死循环当l 1 r时如果mid (l r) // 2mid会等于l某次check成功时执行l midl根本没变循环卡死。反过来如果求最小值却用上中位数可能让r偏移过大结果错。所以每次写二分第一件事就是确认自己是在找左侧边界还是右侧边界然后选择对应的mid取法。光背模板不够。二分答案的核心是check函数。做二分答案题check往往比二分本身更难写它决定了“可行”的判定复杂度。如果check是O(n)那整体复杂度是O(n log L)L是答案范围通常可以接受。我第一次做某些题时总想直接构造最优解结果绕进贪心其实先写一个暴力的check再套二分往往更稳。2.2 动态规划状态定义比转移方程更值钱第二天的主要精力放在DP。总有一个问题会反复出现转移方程到底怎么来的。实际上如果状态定义得足够清楚转移方程是可以推出来的。状态定义本身就是解题思路的核心。以01背包为例代码很多人都会写dp [0] * (capacity 1) for i in range(n): w, v items[i] for c in range(capacity, w - 1, -1): dp[c] max(dp[c], dp[c - w] v)这里从大到小遍历容量是为了保证每个物品只被选一次。如果从小到大遍历dp[c - w]可能已经包含了当前物品那就会变成“完全背包”。这个细节我第一天没理解透第二天把两种背包放在一起对比才彻底搞明白空间压缩后循环方向决定状态更新的“先后顺序”于是决定了物品能否被重复使用。还有一个很容易忽略的点是初始化。求“恰好装满”和求“不超过容量”两种问法初始化完全不同。求恰好装满时一般把dp[0]设为0其余设为负无穷求不超过容量时全初始化为0。我第一次做这类题时题目要求“求刚好达到目标的最少物品数”我把dp都初始化成了一个大数漏掉了dp[0] 0结果一发WA半天才发现。所以读题时先判断目标到底是在约束条件的边界上还是只要在范围内即可。2.3 图论建图方式决定了复杂度第三天是图论。图的存储方式直接决定一道题能不能在时限内跑完。邻接矩阵适合顶点数很少的稠密图O(N^2)的空间适合N在1000以下的场景邻接表适合大多数稀疏图空间O(NM)。我这次有一道题目N可以到10万用邻接矩阵直接内存超限换成邻接表就过了。所以不要急着想最短路径算法先确认图的存储是否合理。BFS的模板可以用队列来实现每个节点入队时标记vis防止重复入队Dijkstra用优先队列核心是每次取出当前距离最小的点更新邻居。写Dijkstra时有一个很常见的坑一个节点可能多次入队如果只在出队时不判断就会用旧的距离重复更新导致复杂度退化。正确做法是在出队时判断if cur_dist ! dist[v]: continue。还有一个容易被忽略的题目变形把BFS的“步数”当成边权为1的最短路。很多迷宫题看着是BFS其实考的是“离终点的最短步数”那就把队里存坐标和一个步数字段就行。如果还能上下左右移动、遇到障碍物也可以套BFS不用真的去写Dijkstra。3. 实操记录与核心环节复盘3.1 Day 1二分与双指针的踩坑实录第一天有4道题。上午第一道是经典的“在有序数组里找目标值”本来以为很稳结果提交后处理数组重复元素时出错。那道题要求返回第一个等于target的下标用标准二分模板会找到任意一个等于target的位置不一定是第一个。解决办法找到target后继续向左收缩右边界。这让我意识到模板只能解决“是否存在/是否满足”一旦要求“第一个”或“最后一个”必须对模板做细微调整。下午做了一道“求最长连续子数组使其和不超过K”的题。一开始我用了两重循环复杂度O(N^2)N是10万显然超时。换双指针之后右指针不断右移左指针就在和不满足时右移。这里的关键是数组元素都是正数。如果数组里有负数双指针就不成立了因为和中途可能变小。这个“为什么双指针能做”的前提比代码本身重要。如果题目没保证正数就得上前缀和加二分或者线段树。晚上补了一道“合并区间”类型的题。这类题第一步永远是排序按区间左端点排序。不排序后面所有判断都是乱的。排序之后扫描每个区间维护当前合并的start和end如果新区间左端点大于当前end说明合并结束否则更新end为两者较大值。代码很简单但我之前总在边界判断上犹豫是还是。其实只要想清楚“在区间端点相接时是否算重叠”根据题意选择即可。大多数题里[1, 2]和[2, 3]是重叠还是相接题目会明说不说的话按惯例可以合并。3.2 Day 2DP状态压缩的一题两解第二天主攻DP遇到一道很典型的“编辑距离”题给定两个字符串求最少操作次数使它们相等操作包括插入、删除、替换。一上来我写了二维DPdp [[0] * (m 1) for _ in range(n 1)] for i in range(n 1): dp[i][0] i for j in range(m 1): dp[0][j] j for i in range(1, n 1): for j in range(1, m 1): if s1[i-1] s2[j-1]: dp[i][j] dp[i-1][j-1] else: dp[i][j] min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) 1状态含义是“s1前i个字符变成s2前j个字符的最小操作次数”。初始化好以后转移方程几乎可以读出来如果当前字符相等直接继承斜对角的结果如果不相等从删除、插入、替换三种情况里取最小。这个题真正卡住的地方是怎么把空间从二维压到一维。因为转移时只用到了上一行的dp[i-1][j]和dp[i-1][j-1]以及当前行的dp[i][j-1]。用一个一维数组时需要用一个变量提前保存dp[i-1][j-1]否则它会被覆盖。我第一版空间压缩代码没保存旧值结果等于替换计算错了。这个坑让我印象深刻空间优化不是单纯把二维降成一维而是要分析每一轮更新时哪些“旧值”仍然需要。3.3 Day 3图论补漏和模板稳定化第三天安排了5道题重点把第二天没弄懂的BFS最短步数问题彻底过了一遍。一道迷宫题在N*M格子里找从起点到终点的最短路径墙不能走。写BFS时最开始的代码用了visited [[False]*m for _ in range(n)]入队时标记。这个是对的但我在第一版里写成了“出队时标记”结果同一个节点被加入队列很多次虽然结果没错但队列大小增长很快差点超时。还有一道求连通块数量的题。这道题其实只要对每个未访问节点调用DFS/BFS即可。DFS的递归写法看起来方便但N很大时有递归深度风险。我这次特意用迭代栈写避免爆栈。深度优先不一定只能用递归用stack [start]循环pop效果完全一样。第三天的统计表格如下日期主要类型题数AC数核心问题3月10日二分、双指针43二分的左边界处理3月11日动态规划43DP空间压缩时的状态覆盖3月12日图论、补漏55BFS入队标记时机这个表格不是拿来晒成绩而是让复盘有依据第二天少AC的那一题第三天其实变成了图论里“状态标记”的提醒。不同知识点之间是有关联的。4. 刷题过程的常见问题与排查技巧实录4.1 样例过但提交全 WA 的排查顺序样例过了提交全错是刷题最挫败的经历。遇到这种情况我有一个固定的排查顺序。第一看题目给的输入范围测一个最小规模的数据比如n0或n1。很多边界条件在样例里不会出现一旦n0数组访问就越界或循环不执行结果是0但正确答案可能是特殊值。第二检查重复元素二分和排序相关的题尤其容易在这里翻车。第三检查整数溢出C里用int还是long longPython没有这个问题但Java需要小心。第四重新读题看自己是不是把“升序”“降序”“可以重复”“最小”这些限定词看漏了。我有一次WA到怀疑人生后来发现题目要求输出排序后的下标而不是值。这种“输出目标理解错了”的失误样例甚至会误导你因为样例恰好没区分。所以刷题记录里我习惯在每道题旁边写一句“题目的输出要求”比只贴代码有用。4.2 TLE 的定位方法提交超时先别急着优化细节。正确的第一步是估算复杂度。如果N是10万O(N^2)一般就危险了O(N log N)通常可以。如果算法复杂度本身没问题再去看有没有多余操作比如在循环里调用了一个本身是O(N)的函数导致整体变O(N^2)却不自知。我曾经在一个循环里写if x in list那个list长度是10万循环也是10万实测跑起来非常慢。换成set之后同样的逻辑瞬间通过。这个“隐性复杂度”比显式的两重循环更难发现因为代码看起来很整齐。排查TLE时的做法是给几个大数据规模的测试分段打印耗时缩小到具体是哪个函数慢线上笔试虽然没有本机测试数据但在本地可以自己构造最大数据先跑一遍。输入输出加速也很重要尤其是在行数很多的题目里。Python的sys.stdin.read()比input()快很多C可以用ios::sync_with_stdio(false)。这些不算算法优化但关键时刻确实能救命。4.3 三天刷题的心态管理三天连刷最难的不是题目而是第三天的疲倦感。第一天还觉得新鲜第二天开始怀疑自己的脑子第三天则是既想结束又怕没收获。我这次特意在第三天安排了图论题因为图论题建模过程有趣能调动积极性。如果发现连续两道题都没思路那就停下来不再开新题。去整理之前写过的模板哪怕是抄一遍到笔记里也比硬着头皮看好评解析有效。整理模板本身就是复习。另一个方法是换一道类型完全不同的简单题找回“我能过题”的掌控感再回到难题上。刷题记录里的数据不用太在意错的题才是重点三天结束之后我复盘最多的是那两道没AC的题它们比9道AC题提供了更多信息。注意如果一道题超过30分钟没有任何进展先把思路和疑点记下来然后换题。情绪消耗比脑力消耗更容易让你提前放弃。三天刷题的记录到这里基本复盘完了。我个人实际操作中的体会是刷题到一定数量之后拼的已经不是代码量而是对模板的理解深度和排除bug的熟练度。这次三天13道题AC11道看似只是一个普通记录但真正有价值的是每一道错题对应的那个具体细节二分边界、DP初始化、BFS入队标记、空间压缩时的旧值保存。如果你也想试试建议也按“知识点分组固定时间块当天复盘”的方式安排哪怕只做三天回头再看的时候你会发现自己对算法的理解比题数更扎实。最后再分享一个小技巧每天结束后把当天所有出错点写成一句话放到手机备忘录里隔两天翻一遍比考前突击笔记有用得多。