LeetCode刷题第10天:算法模板与刷题方法,搭稳基础的分水岭

发布时间:2026/10/19 17:07:59
LeetCode刷题第10天:算法模板与刷题方法,搭稳基础的分水岭 1. 第10天为什么是刷题路上第一道分水岭1.1 前10天隐藏的节奏规律先说实话LeetCode Day10这个节点放到整条刷题时间线里其实很尴尬。它不像Day1那样有新鲜感也不像Day30那样能看到明显的题量积累它恰恰处在一段“热情退潮、正反馈还没到位”的真空期。我自己当年刷到第10天的时候正好碰到一个尴尬的场景简单题开始觉得重复中等题又经常卡住一打开题解觉得自己是个废物合上题解又什么都写不出来。但后来我才意识到第10天根本不用急着追求“秒杀题目”它真正的意义在于完成一次节奏校准。如果你只刷了几天你会觉得算法题靠灵光一现刷到第10天应该开始意识到算法题是一门可以拆解的技能有套路、有模板、有固定的分析路径。这个认知转变比多刷几题重要得多。观察那些能坚持过百天的人前10天几乎都做对了一件事他们没把刷题当成每天必须完成的KPI而是当成一个“建立肌肉记忆”的过程。第1到第7天练的是手感每天2到3道题把数组、字符串、链表这些基础结构写熟练第8到第10天才开始尝试整理题型、归纳套路。如果你从第1天就开始死磕困难题大概率在第5天就崩溃了。如果你到第10天还在每个类型之间乱跳那后面很容易陷入“刷了就忘”的循环。1.2 第10天应该掌握的最低能力线我给自己定过一条判断标准Day10结束的时候如果还不能独立写出这几类代码就先不要急着开新题。第一数组遍历与原地操作的常规写法包括循环里维护索引、交换元素、覆盖写入。像“把数组里的0移动到末尾”这种题即使不熟悉双指针也要能写出一个能跑的版本。第二哈希表的基本用法知道什么时候用字典存索引、什么时候用集合去重。第三简单递归能理解二叉树的先序、中序、后序遍历代码是怎么一层层展开的。第四会算时间复杂度和空间复杂度至少能说出“这个双层循环是O(n²)”“用哈希表能降到O(n)”这种量级的判断。如果这四条里超过两条是虚的那说明前面10天的题基本是“抄题解抄过去的”。第10天最值得做的一件事就是回头把做过的简单题重新写一遍尤其是那些当初看了题解才做出来的题。你会发现能独立写出来和能看懂是两种完全不同的掌握程度。1.3 第10天最容易崩盘的三种状态根据我身边的刷题搭子的普遍经历第10天放弃基本逃不出三种状态。第一种是“贪多型”每天恨不得刷四到五道新题结果每道题都只停留在一知半解。这种状态持续到第10天大脑里已经塞满了零散的题解片段遇到新的题目时根本调不出来挫败感瞬间爆棚。第二种是“死磕型”一道中等题卡了三个小时还不肯看题解。不是说死磕不对但第10天还没有足够的套路储备死磕的效率极低。更合理的策略是20到30分钟没有有效思路就去看题解看完之后关掉题解自己重新写一遍把“看不懂”变成“能复现”这才是有效学习。第三种是“飘了型”连续几天把“简单题秒过”当成自己水平的证明没有留出时间复盘也没有尝试写更系统的解法。简单题秒过很多时候只是因为你之前见过类似的题真的遇到变体就露馅。第10天是个很好的自检时间点先解决这三种状态再谈刷题数量。2. 把每次做题变成一条可复制的流水线2.1 审题阶段先别急着码代码很多人刷题有一个毛病打开题目看到示例大概知道要干嘛就开始写写完发现有两三个边界情况没考虑改来改去一个多小时就过去了。我刷到第10天时最明显的进步就是开始学会“用手推题目”而不是“用眼睛猜题目”。一个实用的做法是在写任何代码之前把题目提供的示例在纸上手动跑一遍并额外构造两个自己的用例。比如题目要求返回数组下标我会先想想如果数组为空怎么办如果没有答案怎么办如果答案可以有多个题目要求返回哪一个这些问题在编码前想清楚能省掉后面大量调试时间。审题阶段还有一个容易被忽略的细节确认输入规模。题目里通常会给数组长度、数值范围等约束这些约束直接决定了你能用的解法复杂度。如果输入规模是10的4次方那O(n²)的算法很可能超时如果输入规模只有100那暴力解法完全可行。第10天起我会强制自己养成一个习惯看完题目先看一眼数据范围再决定写什么复杂度级别的算法。2.2 暴力解不是浪费时间是分析的起点我在第10天之前也犯过一个错误总觉得写暴力解很丢人巴不得一上来就写出最优解。后来踩了坑才发现最优解从来不是凭空想出来的它是对暴力解进行分析之后逐步改进得到的。暴力解的真正作用是帮你验证对题目的理解。先把最直白的方法写出来哪怕时间复杂度是O(n²)或者O(2ⁿ)只要逻辑正确就能作为基线。有了这个基线你才能直观感受到优化的空间在哪里。以“两数之和”为例暴力版本就是两层循环检查每一对数字看到这题的第一反应是先写出这个版本再分析“内层循环到底在做什么”发现内层循环在做的事是“查找一个值是否存在于数组”于是很自然地想到用哈希表来优化查找。如果直接跳到哈希表的解法你可能只知道“这题用哈希表”却不理解为什么能用哈希表。一旦题目变成“三数之和”“和可被K整除的子数组”你照样不知道从哪里下手。所以我建议第10天之后凡是没思路的题先逼自己写一个能跑的暴力解哪怕是TLE也先提交一次。这一步对建立解题直觉特别重要。2.3 优化方向从哪里找暴力解写完之后优化的方向其实有规律可循最常见的是下面这几类。第一减少重复计算。同一个值可能被反复访问或计算用哈希表、前缀和、缓存等方式存储中间结果。这是最通用的优化方向。第二减少不必要的遍历。如果数组已经有序或者你只需要维护某一端的指针可以用双指针把O(n²)降到O(n)。第三换一种处理顺序。比如倒序遍历、先排序再处理、用堆维护当前最大值等这些都属于“改变数据结构或顺序”的优化。判断优化是否有效的标准很简单时间复杂度是否降了一个量级或者空间复杂度是否在可接受范围内。你要记住空间换时间是算法题里最常见的交易绝大多数哈希表方案都属于这一类。第10天的时候能熟练做好这个分析就足够了不需要追求所有题都秒出最优解。2.4 复盘比做题更值钱我做题做了一段时间后把大部分时间从“做新题”挪到了“复盘旧题”上正确率提升反而更快。复盘不是简单看一遍题解而是要把自己的思路和标准解法进行对比找到分岔点在哪里。我会用固定模板做记录大概是四行内容题目编号和一句话描述我的第一反应是什么正解是什么思路差距出在哪里是没想到数据结构还是边界没处理还是理解错了题意。这个记录不要写成抄题解一定要用自己的话重写一遍。你看第10天如果认真留了这10份记录后面再复习的效率会翻倍。另外复盘时我习惯把一个题目的多个解法都写一遍。很多时候你只写了最优解却没写过暴力解导致你对“为什么最优”没有直观感知。两种版本都写一写复杂度对比才会刻进脑子里。这个动作看起来很费时间但对长期刷题而言非常划算。3. 第10天最值得吃透的三套基础模板3.1 哈希表空间换时间的第一利器如果你在Day10前后还不知道什么时候用哈希表那这10天基本是在无效刷题。哈希表的核心作用就一句话把查找某个值是否存在的时间从O(n)降到O(1)。在数组相关题目里它几乎是“对时间复杂度不满时的第一反应”。我们来写一个最简单也最有代表性的代码。题目是“如果数组中有两个数的和等于目标值返回这两个数的下标”暴力解法是两层循环O(n²)的时间复杂度。优化思路是边遍历边记录“已经见过的数”每遇到一个新数就去哈希表里查“目标值减当前数”是否已经出现过。def two_sum(nums, target): seen {} for i, num in enumerate(nums): complement target - num if complement in seen: return [seen[complement], i] seen[num] i return []这个解法的核心要点是先查表再入表这样可以正确处理“每个元素只能用一次”的约束。如果你先把所有数都存入哈希表再遍历查找就会遇到“同一元素被使用两次”的问题比如nums [3, 3]target 6时直接存表也没问题但nums [1, 2, 3]target 2时先把所有数存进去再查找可能返回[0, 0]这就是错解。Day10阶段的哈希表题不需要做得太偏把“两数之和”“是否存在重复元素”“最长连续序列”这几种经典场景吃透就足够支撑你往后继续刷了。3.2 双指针数组和链表上的高效遍历双指针是第10天最容易给人“哇”的套路因为它能把很多O(n²)的问题降到O(n)。最常见的应用场景有两个有序数组上的相向双指针以及数组原地操作的快慢双指针。以“将数组中的0移动到末尾并保持非0元素的相对顺序”为例快慢双指针的写法非常简洁。def move_zeroes(nums): slow 0 for fast in range(len(nums)): if nums[fast] ! 0: nums[slow], nums[fast] nums[fast], nums[slow] slow 1 return nums这里的slow指针指向“下一个非0元素应该放的位置”fast指针负责扫描所有元素。当fast遇到非0元素就把它交换到slow位置然后slow向后移动。交换这一步非常巧妙它能保留之前已经处理过的非0元素也能顺带把0被动交换到后面。整个过程只遍历一次数组时间复杂度O(n)空间复杂度O(1)。第10天容易犯的错误是把两个指针的语义搞混比如不知道slow到底指向哪里、什么时候该移动slow。这里分享一个我自己的记忆方法快指针负责“找”慢指针负责“存”“找”到目标之后把值“存”到慢指针位置慢指针再往前走一步。想清楚这个语义绝大多数快慢指针题都不会写错。3.3 递归与栈二叉树问题的起点有些人到第10天还在刻意回避二叉树这是战略失误。二叉树在算法题里的地位非常高而它的基础无非是递归和栈的配合。前序遍历的递归写法几乎是所有二叉树题目的地基看下面这段代码def preorder(root): if not root: return [] return [root.val] preorder(root.left) preorder(root.right)递归的理解难点在于“不要试图展开太多层要相信函数定义”。你只需要相信preorder(root)返回的就是以root为根的前序遍历结果那么当前层的任务就只是处理root然后分别调用preorder(root.left)和preorder(root.right)。很多人在Day10卡住是因为总想着在脑子里逐层展开一展开就乱了。如果递归写得不稳可以配合栈写迭代版本它们本质是一样的只是把系统帮你压的递归栈换成手动维护的栈而已。def preorder(root): stack, res [root], [] while stack: node stack.pop() if node: res.append(node.val) stack.append(node.right) stack.append(node.left) return res注意栈是先入后出所以我们要先压入右节点、再压入左节点这样左节点会先弹出保证遍历顺序是“根-左-右”。第10天不要求你把各种遍历倒背如流但至少要知道递归和迭代是可以互相转换的这为后面做更复杂的二叉树题目打了很好的底子。4. 从一道题看完整解题链路以“某些求和类题目”为例4.1 第一反应暴力求解为了把前面讲的方法串起来我用一道很经典的题来做完整演示。题目大概是这样的给定一个整数数组和一个目标值请返回两个数的下标使这两个数之和等于目标值。你可以假称这是一道模拟项目X中的需求。我先写出暴力版本def two_sum_brute(nums, target): n len(nums) for i in range(n): for j in range(i 1, n): if nums[i] nums[j] target: return [i, j] return []这个版本很好理解就是穷举所有下标组合。时间复杂度O(n²)空间复杂度O(1)。在输入规模很小的时候完全没问题但一旦数组长度到10的4次方量级两个循环就是10的8次方次操作大概率超时。这里要补一个关键认知判断一道题能不能用暴力解不是看题面而是看数据范围。很多第10天的朋友会因为TLE而怀疑人生其实他们只是没养成先看数据范围的习惯。4.2 优化分析内循环到底在做什么暴力版本的第二层循环做的事情本质上是在“寻找一个数等于target - nums[i]”。这个“寻找”操作放在循环里就是O(n)如果能把每次查找都变成O(1)整个算法就会从O(n²)变成O(n)。这正好是哈希表的用武之地。优化的过程不是玄学是顺着“查找慢就加哈希表”这条线推出来的。我先建立一个空字典键是数组元素的值值是它对应的下标。然后从左到右遍历数组每遇到一个数num先检查target - num是否已经在字典里。如果在说明之前遇到过一个数和当前这个数能凑成target直接返回两个下标如果不在就把当前这个数存进字典。这样一遍遍历就完成不需要回头再找。def two_sum_hash(nums, target): seen {} for i, num in enumerate(nums): complement target - num if complement in seen: return [seen[complement], i] seen[num] i return []为什么必须先“查”再“存”如果先把所有元素都存进去再遍历查询会导致一个元素被匹配到它自己。我用一个很极端的例子说明nums [2, 2], target 4。如果先全部存入字典多次遍历时第1次取到nums[0]2在字典里找到2对应的下标为0于是返回[0, 0]这显然是不对的。先查后存就能天然避免用自己的下标匹配自己。4.3 复杂度对比和边界条件暴力版是O(n²)时间、O(1)空间哈希版是O(n)时间、O(n)空间。这是非常典型的空间换时间。很多初学者一看到O(n)空间就开始担心“空间会不会爆”实际上常见的内存限制下O(n)空间远没有O(n²)时间那么致命尤其是n在10的5次方以内时哈希表存几万个键值对完全没问题。边界条件也值得聊两句。题目如果明确说“一定存在一个答案”那代码里不需要专门处理找不到的情况如果不能确定建议返回空列表。另外如果数组长度小于2也要直接返回空列表虽然两数之和这种题通常不会出现这么短的数组但养成习惯总没坏处。这道题的完整链路看起来简单但它真正展示了方法论先暴力再分析哪里慢然后用合适的结构优化。第10天需要的不是几千道题的广度而是把每道题都走完这个链路直到它成为本能。5. 实操中踩过的坑与排查技巧5.1 超时问题先看复杂度再看常数第10天最容易遇到的报错就是超时。很多人第一反应是“是不是我的代码循环太多导致太慢”但实际上超时的根子绝大多数在最开始就埋下了跟你循环细节关系不大。我会按这个顺序排查第一步看一眼题目的数据范围估算自己算法的时间复杂度。比如数组长度是10的5次方而你的算法是O(n²)那基本可以确定是复杂度问题不是常数优化能救的。第二步确认你的代码在最坏情况下确实会跑满整个复杂度。有些题在平均情况下表现还行但测试用例会故意构造最坏情况比如所有元素都相等、所有数都不满足条件。第三步如果复杂度本身没问题才去检查循环里有没有重复计算、有没有不必要的函数调用、有没有频繁创建对象。这里也有个经验之谈不要为了优化常数而牺牲代码可读性第10天阶段更重要的是学会判断“该不该优化”。有些题你用了哈希表但还是很慢可能是你的哈希表里存了太多无用的中间状态这时候应该回头检查你的更新逻辑而不是盲目换成更复杂的数据结构。5.2 边界条件自己造用例别等测试出报告很多刷题新手习惯写完代码直接提交等平台告诉你答案错误再回去猜哪儿错了。这种模式效率太低我在第10天时把习惯改成了“提交前先自测”效果好了很多。自测时我会构造几类经典边界空输入比如空数组、空字符串单元素输入全相同元素递增或递减序列目标值在两端的情况包含负数或零的情况。以“两数之和”为例我会自己跑一遍nums [3, 3], target 6确保不会返回相同的下标再跑一遍nums [1, 2, 3], target 5确保返回的是[1, 2]而不是[2, 1]。还有一个很隐蔽的边界问题整数溢出。不过Python没有这烦恼刷C或Java的同学就要特别小心了在做加法比较时可以把类型转成更大的范围或者用减法替代加法来避免溢出。Day10阶段不需要过多关注溢出问题但至少要知道有这个坑。5.3 一看就会、一写就废如何破局这个现象太常见了尤其是看题解的时候觉得自己全懂了关上题解自己写又卡在原地。问题出在你只是“认得”了解法但没有真正在脑中重建过它。破解办法只有一个把题解扔到一边凭记忆和思路重写。重写也不是让你背代码而是让你用自己的理解去表达。比如你看懂了双指针解法那就用自己的话描述快指针找非0值慢指针指向待替换位置遇到非0值就交换。然后你写代码的过程中自然会遇到一些细节问题比如交换之后要不要主动把原来的位置置0这些细节恰恰是你看题解时不会注意到的。多来两次这种“重写练习”你才会真正吸收一个解法。第10天阶段“一写就废”根本不是能力问题而是练习方式问题。你不需要做更多新题你需要把做过的题再重写两三遍直到不需要刻意回忆就能写出来为止。5.4 错题本到底该记什么很多人建了错题本但记得像流水账题目编号、错误代码、正确代码。这样的错题本是没有灵魂的。有效错题本的核心应该是记录“当时的思考过程”和“错误发生的地方”而不是记录答案。我自己的格式是四个部分第一这道题我第一眼想用的方法是什么第二为什么那个方法行不通或者不够好第三最终解法里最关键的洞察是什么比如“用哈希表存之前出现过的数来加速查找”第四如果下次遇到类似题我应该优先想到哪个套路。这样的错题本看起来不像笔记更像是一份给自己的“思维提示卡”。第10天时试着把前面10天的错题按这个格式整理一遍你会发现自己对算法的理解已经从“散点”开始连成“线”了。6. 一些关于Day10之后的话6.1 保持固定节奏比追求速度更重要刷题这件事最怕的不是慢而是断。哪怕是每天只做一道简单题也比连续休息三天再一口气刷五道要强。算法思路的建立依赖于持续的输入一旦中断几天你对那些模板的熟练度会明显下降重新捡起来又要花额外的时间。我自己到了第10天的时候最大的收获不是会了多少题而是摸清了自己每天能投入多少时间。比如今天状态好可以刷两道新题加一道复盘状态差就只做一道复用模板的题甚至只做复盘。不要因为某天刷得少就产生负罪感第10天最忌讳的是拿刷题数量衡量自己。6.2 从第10天开始试着给题目分类第10天之前你可能只是按照题号顺序刷或者每天随机从推荐列表里挑题。到了这个节点建议开始有意识地给做过的题贴标签数组、字符串、哈希表、双指针、二叉树的遍历、栈与队列。每做一道题就在记录里加一个标签。这么做的好处会在后面逐步显现。当你刷到第30天、第50天时你会发现很多所谓的新题不过是旧题换了层包装。比如“移动零”考的是双指针“移除元素”考的是同一个模板“删除有序数组中的重复项”本质还是双指针。题目分类得越清楚你的迁移能力就越强下次遇到新题时调取套路的速度就越快。6.3 最后分享一个提升复现率的小习惯第10天这个节点我特别建议你尝试做一件事把你做过的每道题的暴力解和最优解都写到同一个文件里并在注释中写清复杂度和关键思路。我当时用的就是本地的一个文档按日期和标签排列。这样做有两个好处一是复习时能快速看到自己的进步轨迹这对信心维系很有帮助二是当你想不起来某个套路时翻自己的文档比翻题解更快因为那上面记的是你已经消化的领域表达。到Day10那天我把前面积累的十几份记录重新过了一遍才真正有一种“上道了”的感觉。后续的刷题就是在这些模板和套路之上做增量积累。希望这份Day10的经验能帮正在这个节点徘徊的朋友稳住节奏别急着追赶别人的进度先把自己的地基打扎实。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询