ARTICLE DETAIL

资讯详情

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

LeetCode刷题保姆级路线:从入门到进阶的完整指南

LeetCode刷题保姆级路线:从入门到进阶的完整指南 不少刚入门的同学找我要“刷题路线”上来第一句往往是大佬我能不能直接从LeetCode热题榜开始刷我的回答通常是可以但八成会在第二周放弃。我自己就是这么过来的——刚刷完基础语法的我自信满满点上两数之和后面的中等题结果一道题卡了一个通宵评论区里全是看不懂的骚操作第二天再也不想打开那个页面。这篇保姆级刷题指南就是把我从“连递归都写不顺”到“能独立啃下大部分hard题”的完整过程整理出来。里面包含平台怎么选、每天刷多少题、一道题怎么刷才算刷透、必刷基础算法题清单以及我踩过无数次的坑。它适合三类人刚学完编程基础却不知道从哪下手的在校生工作几年想重新补算法功底的开发者以及刷了几百题却感觉进步不大的“题荒”选手。读完不用收藏直接照着做就行。1. 先把刷题这件事想明白它到底在训练什么1.1 刷题的本质不是背答案而是建立“信号到算法”的映射很多人把刷题理解成“多见题型、多背代码”这是最大的误区。题目是永远见不完的LeetCode加上各OJ平台少说也有几万道题你不可能靠穷举来应对。真正的核心能力是看到题面里那些特征词和数据范围立刻能联想到对应的算法套路。我习惯把这个过程叫“信号映射”。比如看到“有序数组”四个字脑子里要立刻拉响警报二分、双指针、归并三选一或者组合上看到“最长子串”“窗口内最大”这类表述优先想滑动窗口看到“所有可能的组合”“全部路径”大概率是回溯加剪枝看到数据范围是10^5你要自动排除O(n²)的暴力转而思考O(n log n)甚至O(n)的解法。这种映射能力不是天生的它是靠大量刷题“喂”出来的但前提是你刷题的时候带了脑子。类比一下就是学开车。新手拿到驾照开上路每一个动作都要想先踩离合、再挂挡、再看后视镜手忙脚乱。老司机不用想一脚油门一脚刹车凭肌肉记忆就能完成。刷题也一样你刚开始看到“树”字还要回忆树的遍历模板刷到一定量之后中序、前序、层序这些结构会像吃饭喝水一样自然。所以刷题训练的不是“记住某道题的答案”而是训练你的“条件反射”。1.2 三个阶段对应三种完全不同的心态我把刷题过程分成三个阶段每个阶段目标和心态完全不同别搞混。入门期前1到2个月目标只有一个AC也就是让代码通过。这个阶段不要追求最优解不要纠结时空复杂度是不是吊打99%的用户能写出来、能跑通就是胜利。因为你的大脑还在建立基础语法的熟练度同时处理“题目逻辑语言实现调试”三件事已经很吃力了再加复杂度优化的负担纯粹是给自己添堵。提高期第3到第6个月目标升级为“在合理复杂度内给出解法”。这时候你应该对自己的代码有要求了暴力解写完停下来想想能不能用哈希表省掉一层循环能不能用双指针把O(n²)降到O(n)。这是算法能力突飞猛进的阶段也是最容易产生快感的阶段——同样的题你用别人一半的复杂度跑完那种爽感确实上瘾。进阶期6个月以上目标变成“面试和竞赛的双重标准”。面试场景里你需要边写边讲思路处理各种边界输入还要能回应面试官的追问“还能不能再优化”以及“如果数据量翻倍呢”。竞赛场景则更极端拼的是在限定时间内对同一道题调出最快的实现路径。这个阶段的刷法已经从“刷题”变成“专门练极限场景”。1.3 刷题的时间预期提前做好心理建设说句实话算法功底的积累是慢变量不可能靠一个月冲刺实现质变。我见过太多人每天刷5道题坚持两周后因为工作/考试中断然后彻底放弃。我更推荐的是“细水长流”模式平时工作日每天40分钟到1小时刷1道题最多2道周末如果有空就做一次完整的模拟练习。宁可每天只刷一道也好过一天猛刷十道然后断更一周。这里有两个具体参数可以分享第一个是一道题的“合理耗时”简单题15分钟、中等题45分钟、困难题90分钟超过这个时间你就已经不是在思考而是在消耗情绪可以看题解了。第二个是“复盘时间”每道题刷完后应该至少花10分钟写笔记这一步很多人偷懒省略其实这才是区分刷题有没有效果的胜负手。回头我单独开一节讲复盘怎么做。2. 平台与工具选型别把宝贵时间浪费在选择上2.1 主平台为什么必须是LeetCode国内现在提到刷题默认就是力扣LeetCode中国区这个选择是有充分理由的。第一题库体量大、质量高尤其“热题100”和“剑指Offer”系列基本是面试题风向标各家公司出题反复绕不开这些考点。第二中文题解生态成熟你卡住的题几乎都能找到别人的解题思路而且按语言分好标签Python、Java、C都能直接看。第三它自带“模拟面试”和企业题库对冲着找工作去的人非常友好。这里我要多嘴提醒一句有位读者曾经问我“leecode必刷基础算法题”怎么找我先纠正拼写——是LeetCode不是LeeCode这词特别容易打错。基础题单也别急到第3节我直接给你列出来照着做就行。还有一个小建议别一上来就直奔困难题。我刚入坑时心态浮躁觉得中等题配不上自己非要挑hard刷结果一天憋不出一道自信心碎了一地。正确打开方式是按专题刷数组刷完刷链表链表刷完刷树每个专题内部再按难度递进这样知识是成体系的而不是散点状。2.2 那些藏在LeetCode之外的OJ平台什么时候用如果你刷到一定阶段或者你是走竞赛路线的那绝不能只盯着LeetCode。“OJ”是Online Judge在线评测系统的缩写国内老牌的比如POJ北京大学、HDU杭州电子科技大学后来又有洛谷、牛客、Codeforces、AtCoder等。它们最大的特点是题目风格和难度梯度与商业刷题网站完全不同洛谷偏信息学竞赛题面硬核但每道题的题解写得非常详细适合想打基础的人牛客非常贴近国内互联网公司的笔试场景尤其是选择题和编程题结合的模式和真实机试很像Codeforces和AtCoder则是每周都有定时比赛适合进阶期练手感和反应速度。这些平台我统一叫“课外补充”。它们不一定要全程刷但每一个都有不可替代的价值。比如我在刷专项动态规划时会在洛谷按难度标签“普及- / 提高”挑题因为洛谷的专题分类比LeetCode更细能精确狙击薄弱环节等到练比赛心态时再上Codeforces打打Div3感受一下时间压力下的代码手速。我个人的经验是“用题目挑OJ而不是用OJ挑题目”。你不需要把所有平台都打满卡而是哪个平台恰好有你当前需要训练的题型就去那里刷。LeetCode覆盖面试主流考点OJ平台则补足难度和题量的宽度。2.3 用“Codebrick”思路管理你的刷题仓库前阵子看到有人提“codebrick刷题”我当时一愣后来才反应过来大家是在互相分享自己的刷题仓库——代码像一块块砖头一样被垒进GitHub所以起了这么个外号。这个思路我非常推荐尤其当你刷题数量超过200道之后你会发现之前刷过的题如果不整理约等于没刷。我自己的做法是这样的在GitHub建一个仓库叫“codebrick”目录结构按算法标签分比如“array/”、“linked-list/”、“dynamic-programming/”、“graph/”然后在每个目录里按“题号_中文缩写”命名文件。每道题除了放最终通过的代码还要塞进一个Markdown笔记记录这四要素逻辑思路用一句话概括核心复杂度分析时间空间边界陷阱提交时掉过的坑以及“这题和哪几道题本质上是一类”的归类。这么做的好处是三个月后复习时你扫一眼笔记就能想起来自己做过的每一道题而不是看着一堆文件名发呆。除了GitHub我用Obsidian做本地笔记库配合双链把同类题目串起来。比如“接雨水”它会关联到“柱状图中最大的矩形”和“盛最多水的容器”三者都用到了单调栈或双指针的思路。你不需要一开始就用花哨的工具一张电子表格或者一个备忘录App只要能坚持记录效果都一样。2.4 平台选择速查表一张表格秒懂差异我顺手整理了一张表把几个常见平台的核心差异给列出来方便你按需选择。平台核心特点适合人群费用情况是否支持PythonLeetCode / 力扣题库大中文题解企业题库模拟面试绝大多数求职者大部分题库免费会员解锁更多支持洛谷信息学竞赛向题解极其详细专题分类细刷基础算法、竞赛入门免费支持牛客网贴近国内大厂笔试选择题编程题混合准备校招、实习免费题库为主支持Codeforces高频周赛题目考察思维深度进阶、竞赛爱好者免费支持提交时选PyPy更快AtCoder日系竞赛题面简洁难度梯度清晰入门到进阶的算法练习免费支持如果你只想用Python刷题上面这些平台的免费题库完全够用根本不需要付费。“Python刷题网站免费”这个关键词我替大家验证过了LeetCode基础题免费刷洛谷全免费牛客的经典题库免费刷题记录也可以达到几千题唯一要付费的是某些“进度分析”“面试题解锁”增值功能对初学者而言没必要开。3. 保姆级刷题路线从0到进阶的必刷题单与学习顺序3.1 第一阶段基础数据结构基础算法题前8周很多人问“LeetCode基础算法题必刷哪些”我先说思路第一阶段不是贪多而是把每个数据结构的代码模板写熟。下面这组题单是我参考热题榜并结合自己教学经验整理出来的按专题排列难度都是从简单到中等递增。数组专题第1题“两数之和”必须会至少两种解法第26题“删除有序数组中的重复项”第27题“移除元素”第121题“买卖股票的最佳时机”。链表专题第206题“反转链表”这题是整个链表的基石迭代和递归都要写第21题“合并两个有序链表”第141题“环形链表”第876题“链表的中间结点”。栈和队列专题第20题“有效的括号”是必刷中的必刷第155题“最小栈”第232题“用栈实现队列”。树专题第144/94/145题“二叉树前/中/后序遍历”第102题“二叉树的层序遍历”第104题“二叉树的最大深度”第226题“翻转二叉树”。字符串专题第344题“反转字符串”第242题“有效的字母异位词”第125题“验证回文串”。排序和搜索第704题“二分查找”第278题“第一个错误的版本”第912题“排序数组”练手排序实现。哈希表第1题已覆盖另外第383题“赎金信”。递归入门第509题“斐波那契数”第206题“反转链表递归版”。这大概40道题左右足够刷满前8周每周一个专题周一到周五每天做1题周末把本周专题题目重写一遍。重写不是再写一遍答案而是关掉题解从空白编辑器开始强迫自己回忆起思路。3.2 第二阶段高频题型专项突破第9到20周基础模板熟练之后第二个阶段要进入“组合技巧”的训练这部分才是面试里的重头戏。我按考点频率给你排个优先级双指针/滑动窗口这是数组和字符串里最高频的技巧。必刷题包括第3题“无重复字符的最长子串”第76题“最小覆盖子串”第209题“长度最小的子数组”。刷这几道题要学会的口诀是右指针扩展窗口左指针收缩窗口用哈希表维护窗口状态。二分查找进阶第33题“搜索旋转排序数组”第153题“寻找旋转排序数组中的最小值”第34题“在排序数组中查找元素的第一个和最后一个位置”。二分题目的核心就是边界处理虽然看起来很短但这是翻车率极高的一类。回溯法第46题“全排列”第78题“子集”第79题“单词搜索”第22题“括号生成”。回溯的通用模板是“递归撤销现场”这几题吃透回溯的思路就稳了。动态规划这是劝退最多人的专题我建议不要直接碰困难题从第70题“爬楼梯”开始然后第198题“打家劫舍”第322题“零钱兑换”第300题“最长递增子序列”第1143题“最长公共子序列”第416题“分割等和子集”。动态规划的共性是把问题拆成子问题写清楚状态转移方程。这里有个笨但有效的训练法每道dp题都自问三个问题——dp[i]表示什么初始值是多少转移方程是什么三个问题答完代码基本就出来了。其他高频专题还包括堆第215题“数组中的第K个最大元素”、第347题“前K个高频元素”图与并查集第200题“岛屿数量”、第684题“冗余连接”前缀和/差分第303题“区域和检索”第560题“和为K的子数组”单调栈第739题“每日温度”第84题“柱状图中最大的矩形”。3.3 第三阶段进阶题型与综合套路6个月以后到了这个阶段你已经有了一定题量和手感可以开始碰那些真正的硬骨头了。我不主张每个人都去卷竞赛级算法但如果你想突破天花板下面这几个方向值得花时间状态压缩DP代表题如“划分为k个相等的子集”“最短路径问题变种”它用二进制表示集合状态是一类思维量很大的动态规划。树形DP典型如“打家劫舍III”“树的直径”需要在树上做递归状态转移。数位DP“不含连续1的非负整数”这类题专门处理“某个区间内满足条件的数字个数”。线段树/树状数组“区间和查询”的进阶版常用于高频区间修改问题是比“前缀和”更通用的结构。字符串高级算法KMP第28题“实现 strStr()”里可以练Trie前缀树第208题这些在面试中出现的频率不高但一出现就是区分度很大的压轴题。进阶阶段还有一项重要训练限时模拟。每周抽90分钟随机选一套中等难度以上的题组完全模拟面试环境不翻题解、不限语言、盯着计时器写。我这么练了两个月最大的收获不是手速变快而是“卡住时的心态”稳了——你能学会在几分钟内决定“这道题我先写暴力再优化”还是“换思路”。3.4 复习机制题单维护比刷新题更关键刷题到了一定阶段一定会撞到遗忘曲线曾经会做的题过三个月再看就跟新题一样。这是正常的不需要焦虑但要靠复习机制来对冲。我的复习规则很简单把做过的题分为“绿熟练、黄勉强、红不会”三档。每周日只复习黄色和红色的题每个月抽查上个月标绿的题能否不卡壳写出来。复习方法不是看题解而是“空写核心思路”把代码注释写出来说明这题用哪个数据结构、复杂度多少、边界是什么。如果连思路都想不起来就把这道题重新做一遍然后更新笔记里的“三个月后重做”标记。4. 实操过程一道题从卡住到吃透的全流程拆解4.1 拿到一道题后的“黄金10分钟”很多新手拿到题就直接开写代码这是错误的。我现在的标准流程分为四步第一步读题。读题至少花3分钟不是过一眼而是把题干的每个约束都圈出来。重点看数据范围比如n是否小于等于10^5决定你能否用O(n²)解法、输入是否有序、是否有重复元素、是否需要原地修改。第二步举例子。自己手搓两三个样例包括正常情况和一个极端小样例空输入、单元素这样能提前卡掉很多低级错误。第三步暴力解。哪怕效率很差也先在心里或者草稿纸上过一遍暴力思路因为暴力解是验证算法逻辑是否正确的“基准答案”。第四步问自己“能不能更好”暴力解法哪里浪费了时间是重复扫描还是多次遍历顺着这个点去思考优化空间。我观察过很多刷题新手他们的问题不是太慢而是太快跳过前三步直接写代码最后被困在“逻辑看着对但越调越乱”的泥潭里。磨刀不误砍柴工前期多花这10分钟后面省下的是至少两小时的调试时间。4.2 以“两数之和”为例从暴力到哈希的完整思考用第1题“两数之和”做一个完整示范。题目给定整数数组nums和一个整数目标值target返回和为目标值的两个数的下标。第一步看数据范围如果数组中元素数量n是10^4级别那么O(n²)的暴力可能勉强通过但当面试官问“如果n是10^6呢”暴力就彻底不行了。暴力解很直接两层循环对每个i找后面的j校验nums[i] nums[j] target。时间复杂度显然是O(n²)。优化的突破口在于内层循环每次都是从头到尾找“target - nums[i]”这个值。可以把“已经扫过的值”存进哈希表这样查找某个值是否存在就变成了O(1)。具体做法是遍历数组对于当前元素x先检查哈希表里有没有target - x如果有直接返回两个下标如果没有把x和它的下标放进哈希表。整体一次遍历搞定时间复杂度O(n)空间复杂度O(n)。这就完成了从暴力到最优的优化过程。这里要特别注意一个边界细节很多人问“能不能先把所有元素放入哈希表再找”可以但会有问题——如果target恰好是某个元素的两倍就会把同一个元素自己和自己配对。常见的规避办法是边遍历边查这样查到的target - x必然在x之前出现天然避免自配对。这类细节就是刷题时该重点记录的“边界陷阱”。4.3 写代码时的三个自查清单写代码阶段我给自己固定了三轮自查。第一轮查“边界和空值”数组是否可能为空字符串是否可能包含大小写链表能否为空第二轮查“索引和越界”循环变量是否可能越界指针移动是否会错开尤其注意动态规划里dp[i-1]在i0时的情况。第三轮查“溢出和类型”虽然Python的大整数可以飞起但有些语言里整数溢出会导致结果错误面试场景下要主动提及“这里我会用64位整数来避免溢出”。提前把这些自查项写进肌肉记忆能省掉一大半的提交报错。我记得自己刷“最小覆盖子串”时连续三次下标越界问题都出在窗口左边界收缩时没有保证left right后来养成了“每次移动指针后确认边界合法性”的习惯这类错误基本绝迹。4.4 复盘模板用一张“题解卡片”把题彻底锁死一道题提交通过并不代表这道题归你了。我坚持每道题写“题解卡片”格式固定几个字段一句话思路这题的核心解法是什么比如“用哈希表记录访问过的数字实现O(n)查找”。复杂度时间O(n)空间O(n)。边界陷阱写错过的点比如“忘记处理空数组”“忘记考虑target等于两倍自身元素”。同类题目这题和XXX是同一类思路。把同类题串起来是刷题最有价值的动作。我很多人觉得这很麻烦但你想想刷一道题花40分钟如果只得到“通过了”三个字那么时间就只换来了一个小小的成就感。如果加上10分钟复盘你能把这道题的思路模式、易错点和同类联系全部沉淀下来。这个回报率是最划算的。5. 常见问题与排查技巧实录5.1 数组越界和索引错误最常见的翻车点我在带人刷题和看题解回复的时候最常见的报错就是IndexError或Segmentation Fault。这类问题背后通常藏着三个原因第一循环条件写成了l r但在区域已经为空时还继续访问中间索引第二动态规划的状态数组没有考虑长度为0的情况第三双指针里left和right位置出现重叠后代码没有立刻退出。排查技巧很朴素在代码里插入临时的print/log看关键变量的值变化或者连续列出几个边界小样例比如数组长度为1、长度为2、目标值在首尾元素。这些操作看似简单但比盯着屏幕发呆快十倍。进阶一点的技巧是写二分查找时统一用“左闭右开”写法即left从0到nright从n开始这样能消除大量边界错误。5.2 提交一直TLE超时四条路径逐个试超时的本质是“复杂度不达标”或者“常数过大”。我一般按四条路径排查降低算法复杂度O(n²)能不能用哈希/双指针/二分降到O(n log n)或O(n)这是质变。2. 剪枝尤其是回溯和搜索类题目剪枝往往能把指数级大数据降到可接受范围。3. 记忆化递归里大量重复计算时加一个缓存字典把算过的子结果存起来这是动态规划的前身。4. 优化常数同样复杂度下能写数组不要写链表能用局部变量少用全局属性Python里尽量用列表推导替代显式循环。另外如果你用Python提交Codeforces这类平台可以选PyPy解释器常数性能有明显提升。5.3 递归栈溢出学会“手动模拟栈”深度很大的递归比如链表的递归反转、树的深度遍历很容易卡爆系统栈报出RecursionError。最直观的方案是把递归改成迭代加显式栈自己维护一个栈数据结构把需要“先处理完子问题再回来”的状态压进去。以“二叉树前序遍历”为例递归版本很好写但迭代版本也很经典先把根节点入栈每次弹出节点时记录值再把右孩子、左孩子依次入栈因为栈后进先出才能保证左孩子先处理。如果不想改迭代也有个取巧方案在Python里用sys.setrecursionlimit提高递归深度上限。但这是治标不治本如果递归深度可能到10^5甚至更多还是老老实实改成迭代吧。这道题刷的就是数据结构底层原理值得多花时间。5.4 看不懂题解怎么办5分钟规则和曲线学习初学者最容易心态爆炸的场景就是打开题解看到人家用小几十行代码就AC了一道困难题自己完全看不懂。我的建议是采用“5分钟规则”看题解前先硬想5分钟能想到什么算什么5分钟后打开题解只看“思路解析”不要看具体代码看完用嘴说一遍思路再自己写出代码。如果还是看不懂那就把题收藏起来过一周再回来做一次。这里有个反直觉的经验当时死活看不懂的题硬啃一小时后你只会记住那些“天外飞来”的奇技淫巧还不如先去刷几道简单题积累自信过两天带着“见多识广”的视角回来再看往往一下子就通透了。这种“曲线学习”方式符合大脑的处理机制强记只会加深焦虑。5.5 刷不进状态怎么办建立小反馈机制坚持不下去是刷题路上的最大敌人。我的解法是把反馈周期压到足够短每天都给自己定一个“最小目标”——只刷一道简单题也算完成今天任务每完成一个专题就在题单上划一个勾给自己一点实际奖励。另外一个特别有效的小技巧是把刷题记录发到学习社区或者码农群里找个同好互相监督。群里的氛围带来的推进力比自律大多了。下面把前面提到的常见问题整理成速查表方便你遇到问题直接对号入座报错/现象常见原因排查/解决方案IndexError / 段错误数组越界或指针越界检查循环条件手动跑边界样例RecursionError / 栈溢出递归深度过大改迭代或调大递归上限内存超限MLE空间复杂度过高检查是否有重复缓存减少三维数组答案错误WA边界逻辑错误/没考虑空值造更多样例逐一对照输出TLE超时复杂度不达标降复杂度→剪枝→记忆化→优化常数不知道从哪开始缺乏路线按本文第3节专题顺序刷最后再分享一个我自己坚持到现在的小习惯每周日以后我都会把题单翻一遍把上周标“黄”的题重新写完然后把新的“黄”题转移成“红”题的概率压到最低。我见过太多人刷了上千题却始终在重复自己熟练的内容遇到新类型依然懵——问题就出在不复盘、不归类。刷题这件事数量从来不等于质量真正让你成长的是每一次“原来还能这样想”的瞬间以及把这些瞬间用笔记和复习稳固下来的过程。从今天开始按这份指南的节奏跑起来三个月后你回头看一定会感谢当初那个没有放弃的自己。
返回列表