多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

LeetCode 200题精讲:算法面试刷题方法与题型收敛指南

LeetCode 200题精讲:算法面试刷题方法与题型收敛指南 简介吴师兄学算法Leetcode精讲200题是一份面向算法初学者与准备笔试面试的编程学习者的PDF电子书。内容以“刷经典题而非题海”为核心理念整理出205道精选LeetCode题目并专门为入门者设计了循序渐进、由易到难的刷题顺序每天投入两小时两个月左右即可完成全列表尤其适合新手小白转型、计算机基础薄弱者系统起步。资源为单个PDF文件压缩包大小19.83MB目前已有178人浏览学习。内容以动画视频讲解配合代码注释的形式呈现弱化冗长文字并附有参考网站与作者微信交流渠道方便获取后续更新。除了算法方法论外书中还覆盖Python与Java基础语法要点并针对代表性题目如LeetCode 26题“删除有序数组中的重复项”给出Java、C、Python三种语言的参考代码与指针思路拆解帮助读者理解原地修改数组、去重等高频考点。整体而言这份PDF将刷题顺序、语言基础、实战解析有机整合在一起是一份把算法学习路线落到具体操作层面的实用资料。1. 一份200题精讲PDF凭什么比刷满1000题更接近真实面试水平手边这份「吴师兄学算法Leetcode精讲200题.pdf」在网上流传了很久很多人把它当作「又多了一份题解」收藏起来。我的看法不太一样它的价值不在题量而在「按题型收敛」这套思路。200道题按专题排开每个专题只挑最高频的结构反复练比按编号从头往下刷到800题更能建立面试需要的题型坐标系。大多数人的问题不是题刷得不够而是题型覆盖不均、只刷不总结。这个方向适合两类人一是刚准备求职、不知道从哪下手的初学者二是刷过几百题但一进面试就发挥不稳的熟手。下面我按「先看懂地图、再动手执行、最后验证掌握」的顺序把这套方法完整拆开。2. 200题背后的算法地图题型占比、专题顺序与资料定位一份精讲资料值不值得投入先看它的题型分布是否合理。如果200道题里二叉树占了80道、动态规划只有2道那它更适合当补充材料不能当主线。2.1 题型占比为什么数组和二叉树占了三分之一按一线算法面试的高频分布200道题的大致比例应该是这样专题常见考查点建议占比数组与哈希两数之和、前缀和、原地操作约20%双指针与滑动窗口有序数组、连续子串、链表环约12%栈与队列括号匹配、单调栈、层级遍历约10%二叉树与递归遍历、最近公共祖先、路径和约15%回溯与DFS排列组合、岛屿数量、状态枚举约10%动态规划爬楼梯、背包、子序列约15%贪心与排序区间合并、会议安排约8%图与拓扑邻接表、环检测、拓扑排序约5%其他位运算、堆、二分查找约5%这个比例不是某份文档的原文而是我按刷题社区里常见的高频考点整理的通用分布。用它对照你手上的200题能很快发现偏科。比如你手里的资料动态规划占比不到10%就说明这套题的主线倾向「基础结构」DP需要自己补充。反过来如果DP占了三成前期刷起来会非常吃力不适合零基础起步。为什么数组和二叉树加起来能到三分之一因为数组是所有容器的最底层形态哈希、双指针、前缀和全部建立在它上面而二叉树是练习递归最好的载体递归思想又是回溯、图、动态规划的公共基础。把这两个板块吃透后面很多题其实是在复用同一套思维只是包装不同。2.2 精讲的价值不在答案在「从暴力到最优的思路轨迹」很多人看题解只看最终代码这是最亏的用法。一份好的精讲题解最有价值的部分是中间那段「为什么一开始想到暴力然后从哪里发现可以优化」的推导过程。以两数之和为例。暴力做法是两层循环O(n^2)。优化的突破口在于内层循环做的事情是「查找」而查找一个值在不在集合里正是哈希表最擅长的事情。于是外层遍历数组时把遍历过的值放进哈希表内层查找就从O(n)降到了O(1)。这个「把查找换成哈希」的思路不只是这道题能用后面遇到变位词分组、连续子数组求和、判定重复元素全是同一招。所以我在看精讲时有个习惯先盖住解析花5分钟写一版自己的解法哪怕是暴力的再打开解析逐行对比。对比的重点不是代码差异而是「我的思考在哪一步断掉了」。这一步断掉的地方就是这道题真正要学的东西。把这个断点记下来比抄一遍完整代码有用得多。2.3 按依赖顺序推进专题数组→链表→栈队列→二叉树→回溯→动态规划200道题不能按题目编号从头刷要按专题依赖关系排顺序。我一般会这样安排数组与哈希最先因为几乎所有题都依赖遍历和容器操作双指针紧接着数组它解决的「有序数组两个端点互相逼近」依赖排序和下标操作栈与队列需要的容器概念在数组链表之后学更顺手二叉树放在回溯之前。回溯本质上是「递归 撤销选择」递归不熟练就去做回溯很容易陷入死循环出不来的焦虑动态规划放在回溯之后。DP的很多状态转移其实就是把回溯里的暴力搜索改成记忆化再改成自底向上的递推图放在最后因为邻接表的BFS/DFS可以看作「多叉树 回溯」的延伸。按这个顺序推进每一层新知识都能从旧知识里长出来不会出现「这条路我完全没见过」的断裂感。反过来如果有人一上来就刷动态规划大概率前20题就把热情耗光了。3. 用「三层刷题法」跑通200题计划模板与代码框架把200题拆成专题之后每一道题具体怎么过只看一遍答案没有任何用。我用的方式是三层递进跟写、独立重写、限时模拟。3.1 第一层「跟写」先自己写10分钟再对照精讲改错第一层不是照抄而是「带着自己的半成品去对答案」。看到一道题先用10分钟在纸上写出输入、输出、约束然后写一版自己的解法哪怕暴力解也行。写不出来也没关系这个思考过程会让后面看解析时更容易记住关键点。以二分查找为例这是200题里复用率最高的模板之一def lower_bound(nums, target): # 在有序数组 nums 中找到第一个 target 的下标 # 统一用左闭右开区间 [left, right)避免边界混乱 left, right 0, len(nums) while left right: mid (left right) // 2 if nums[mid] target: left mid 1 # mid 太小左边界右移 else: right mid # mid 可能是答案右边界收过来 return left逻辑说明这段代码找的是「第一个不小于目标值的位置」也就是lower_bound。核心不变量是答案始终在左闭右开区间[left, right)里。当nums[mid]小于target时mid位置不可能是答案所以left直接跳到mid1否则mid可能是答案right收到mid而不是mid-1这样不会漏掉相等的情况。参数说明nums必须是升序数组target是查找值返回值可以直接当插入位置用也能用来判断target是否存在——返回下标在长度范围内且nums[ret] target才表示存在。常见误用是有人把right初始化为len(nums) - 1然后用left right的写法两种写法都可以但不要混着用。选定一种并固定下来比纠结哪种更好更重要。3.2 第二层「独立重写」合上解析把卡点留在纸上第一层学完的题隔1到2天做第二层关闭所有解析在编辑器里独立重写一遍。这一步的目标不是「写对」而是「暴露卡点」。def length_of_longest_substring(s): # 经典滑动窗口找出不含重复字符的最长子串长度 left 0 # 窗口左边界 max_len 0 seen set() # 当前窗口内的字符集合 for right, ch in enumerate(s): # 遇到重复字符从左边收缩窗口直到把重复字符移出去 while ch in seen: seen.remove(s[left]) left 1 seen.add(ch) max_len max(max_len, right - left 1) return max_len逻辑说明外层for循环让right一步步向右扩展窗口窗口内用set维护「当前无重复字符」的状态。每次加入新字符时如果它已经在set里说明窗口内出现了重复项于是从左边逐个移除字符直到把这个重复字符从窗口里清掉。每次操作后窗口都是无重复的所以可以放心更新最长长度。参数说明s是输入字符串left和right分别是窗口的左右边界构成闭区间[left, right]seen里存的是当前窗口内出现的字符。需要注意while循环移除的s[left]不一定是重复的那个字符可能要先移除几个「无辜」字符才能到达重复位置这是滑动窗口收缩的正常过程。如果这一步写得卡壳多半是没想清楚「窗口不变量」是什么。独立重写时我会在代码注释里记录两个东西一是卡在哪个位置超过5分钟二是当时为什么想歪。这两行记录比代码本身更值钱因为面试官问的「你当时怎么想到的」答案就藏在这里。我见过太多人把这道题背下来结果同样是滑动窗口的变式题一改条件就不知所措。3.3 第三层「限时模拟」用一页纸模板固定高频套路前两层过完的题进入第三层限时模拟。简单题15分钟中等题30分钟困难题45分钟。到时间没写出来就停下看解析然后把这道题标记为「待二刷」。这个阶段同时做一件事把某一类题归纳成一页纸模板。from collections import deque def level_order(root): # 二叉树层序遍历按层返回节点值的二维列表 if not root: return [] res [] q deque([root]) while q: level_size len(q) # 先固定本层节点数防止把下一层混进来 cur [] for _ in range(level_size): node q.popleft() cur.append(node.val) if node.left: q.append(node.left) if node.right: q.append(node.right) res.append(cur) return res逻辑说明层序遍历的关键是「先进先出」所以用队列。每次进入while循环时队列里恰好是当前层的全部节点用level_size先记录下来再一次性弹出这一层弹出的过程中把下一层的左右孩子追加到队尾。如果不固定level_size循环会悄悄把下一层的节点也当成当前层处理输出就会错乱。参数说明root是二叉树根节点q是存放节点的双向队列res是二维列表每一层一行。这个模板还能迁移到「按层处理」的很多场景比如求每层最大值、填充下一个右侧节点指针、找最底层最左节点改的地方只是内层循环里对cur的处理逻辑队列结构完全不用动。一页纸模板不需要长每个专题控制在15行以内写清楚三件事识别条件这道题怎么看出该用这个套路、复杂度、易错点。这些模板是后面章节要讲的「模板库」的核心素材。3.4 一周计划模板每周只推一个专题不贪多200题不是一个月能刷完的按周推进更现实。我常用的计划是这样的时间内容题量周一新专题第一层「跟写」4题周二新专题第一层「跟写」4题周三对周一、周二的新题做第二层「独立重写」6题周四新专题继续跟写 前一个专题补漏4题周五本周全部新题做第二层4题周六限时模拟混合专题3题各30分钟3题周日整理模板库 重做本周卡壳的题不定这个节奏每周新题稳定在12道左右但复习量比新题量还大。很多人刷了200题还是没进步问题不在量在复习比例太低。我见过有人一个月刷了80道新题从不回头看旧题面一次挂一次不是不会做是全都忘了。提示如果你每天只能投入一小时就把周三和周五的独立重写当作底线其他天的跟写可以少到每天2题。放弃跟写还能接受放弃独立重写基本等于白刷。4. 刷LeetCode最容易翻车的五个坑现象、原因与排查路径这章写的都是高频踩坑场景覆盖了我自己和其他人反复出错的位置。每一条都按现象、原因、解决三步拆方便你对照排查。4.1 题解看得懂合上资料就写不出来现象看精讲解析时每一行都懂甚至觉得「这题不过如此」合上PDF自己写第一行就卡住十几分钟憋不出一个函数签名。原因看题解是被动输入大脑会产生「我会了」的错觉。实际做题是主动输出需要自己完成「识别题型→选数据结构→写边界→验证」整条链路链路里任何一环没练过都会断掉。解决把顺序调换成「先写后看」。拿到题先写10分钟写不出再打开解析打开解析只看到思路部分不看代码然后自己接着写。这一步可以把「看懂了」的虚假掌握感直接挤掉。刷题不是看谁收藏的题解多是看谁能徒手写出来。4.2 本地能跑一提交就数组越界或空指针现象代码在自己电脑上跑示例通过放到在线判题平台上下标越界、空指针一堆红色错误。这是最常见的翻车现场。原因本地测试用例只有一两个而且恰好是「正常路径」判题系统会在输入里放空数组、单元素数组、最大值边界。这些边界情况你在写代码时根本没考虑。解决写代码之前先在注释里写三个用例空输入、最小规模、最大规模。比如数组题先问自己「nums为空时第一个if能不能兜住nums只有一个元素时循环里会不会越界」然后把这三个用例在本地跑一遍再提交。这个习惯能挡掉八成提交报错。4.3 模板默写成功换个问法就不会现象二分查找模板背得滚瓜烂熟面试官把「有序数组找目标值」改成「旋转后找最小值」、把「找目标值」改成「找第一个大于目标值的位置」就直接卡住。原因背的是代码不是「这个模板解决什么问题」。二分查找不是一段代码是一种「每次把搜索空间减半」的思维。题目包装变一下识别条件就失效了自然无从下手。解决给每个模板写一句「触发条件」贴在模板库最上面一行。比如「有序数组 查找 → 二分连续子数组 区间最值 → 滑动窗口或前缀和树形结构的路径/深度 → 先想递归返回什么」。写不出来这个条件说明这道题还没真正内化。4.4 刷到100题前面的专题开始遗忘现象刷到第120题时回头做第20题的同类题感觉很陌生解题时间比第一次还长心态直接崩。原因没有间隔重复。大脑对「刚学会但不常用」的信息遗忘速度极快当时做对了只代表短期记忆不代表长期掌握。解决给错题本设两个复核时间点一周后、一个月后。每周六不学新题只重做本周错题再到整月节点把错题本里标记「一个月」的题全部过一遍。遗忘的本质不是记性差是复习节奏没跟上。这个坑最隐蔽也最致命因为当事人常常以为是学得不够结果是复习不够。4.5 数据结构选型翻车栈、队列、set、dict没建立条件反射现象遇到「设计一个支持常数时间访问的队列」「判断括号匹配」这类题要想很久才选对数据结构甚至选错导致复杂度不合格。原因对四种基础结构的适用场景没有形成条件反射每次都是现场试错面试现场根本来不及。解决整理一张选型速查表背下来存在性与去重→set键值映射与计数→dict最近相关性配对、撤销→栈排队与层级处理→队列。面试里先说「我用XX结构因为XX」再说代码这句话本身就是得分点。选型说错了代码写对了也救不回来。注意踩坑不可怕可怕的是踩完不知道自己错在哪里。上面五条每一条都可以靠改流程而不是加练题量解决。5. 从「看得懂题解」到「面试讲得清」复述训练与变式迁移刷题最终要过面试这一关。面试考的不只是写对还有「在规定时间内讲清楚思路」。这需要单独练不能靠刷题顺带完成。5.1 四步话术把一道题讲成一个两分钟有逻辑的故事我给自己定了一个固定的讲解框架每道题的讲解都按四步走第一步题目转译。不念原题用自己的话说清输入、输出、约束。比如两数之和我会说「给一个整数数组和一个目标值返回两个下标它们对应的值加起来等于目标每个输入恰好一个答案。」这一步的目的是证明你读懂了题。第二步思路推导。先给暴力解再说怎么优化。暴力是两层循环O(n^2)优化的点是把内层的「查找」换到哈希表里做O(1)命中整体O(n)。第三步代码走读。不逐行背只讲三行关键代码为什么建立哈希表、为什么先查再存、为什么返回之前查到的下标。第四步边界与复杂度。主动说「nums只有一个元素时查不到返回空最坏情况所有元素都互不相同空间复杂度O(n)。」一个合格的讲法大约两分钟。讲的时候不要背而是像在向同事解释你的代码一样自然。我自己练的时候会对着镜子讲后来发现录音回放效率更高。5.2 自己当面试官录音回放与自问清单没有真实面试官的时候自己组局。我会把题目往手机上一放用自带的语音备忘录录音当作模拟面试。讲完回放只听两件事一是卡壳的地方。超过3秒没说出话的位置大多是思路没理顺在错题本上标「表达生疏」。二是逻辑连接词。如果通篇都是「然后、然后」说明只是在回忆步骤没有理解步骤之间的关系如果能在每步之间用「因为…所以…」串起来才算真的懂。自问清单也固定下来输入为空怎么办元素全部相同怎么办整数溢出吗如果数据量翻倍现在的复杂度还行吗这四个问题覆盖了大多数边界翻车。5.3 二刷过滤器用三条标准判断一道题是否真的掌握刷完不等于掌握。我判断一道题能不能过用三条标准标准具体表现达标线隔周重做不看解析独立写出并通过正确率80%以上讲得出「为什么」能说清这个解法为什么是最优而不是「我做过这题」连续3次都讲顺能做变式迁移两数之和改动成三数之和、最接近目标值能说出改动点现场能推导如果一道题里有两条满足不了把这道题退回第二层「独立重写」而不是直接翻篇。变式迁移是最硬的一条标准它证明你掌握的是问题结构不是题目原文。算法面试考的是迁移能力不是记忆力。6. 200题刷完后的三个习惯错题本、模板库与每周自测刷完200题不是终点收尾阶段这三个习惯能让前面所有功夫不白费。6.1 错题本只记卡点不抄题解我的错题本每行一张表的格式日期题名题型卡点一句话解法下次复核第X天两数之和变体哈希没想到先查再存查找用哈希边遍历边查1周后这里的关键是「一句话解法」必须用自己的话说写不出来就说明这道题还没消化。整本错题本不该出现超过一行的完整代码抄代码是抄给别人看的记卡点是记给自己用的。把错题本记成题解合集是这阶段最常见的翻车方式。6.2 模板库按「识别条件、复杂度、框架代码、易错点」组织模板库我用一个Markdown文件维护每个模板五段识别条件、复杂度、框架代码、易错点、典型题。文件控制在15个模板以内超过就合并。模板库不是网上题解的大杂烩只留你自己写过的、经过独立重写的版本。面试前一周我只做三件事把模板库一页纸打印出来过一遍、把错题本扫一遍、每天限时做一道中等题热身。不开新题不碰难题保持手感比挑战边界重要得多。这个流程看起来很朴素但每次都能让状态快速回到正轨。6.3 每周自测周六限时混题周日重做错题平时周一到周五是按专题刷的但面试不会提前告诉你今天考哪个专题。所以每周一定要有「混题」时间周六限时45分钟做3道不同专题的题周日重做本周错题。混题自测的目的有两个一是训练「看到题目先判题型」的反应速度二是检验这一周的知识是不是真的稳了。如果混题正确率低于70%下周不要开新专题把本周的内容再巩固一轮。我最后想留一个具体的教训。有次面试面试官把有序数组查找改成「先旋转再查找」我上来就默写二分模板边界条件全部想错在代码写到一半的时候就已经知道不对劲了。那次之后我给自己立了个规矩任何模板先说出「这个模板的边界在哪里」再动手写。这个习惯让我在后来的面试里稳定了很多表面上是多了一句废话实际上是在强迫自己从「背代码」切换到「讲思路」。同样在刷200题的你如果现在还在为「刷完就忘」发愁大概率不是刷得不够是复习得太少。希望帮到你。本文还有配套的精品资源点击获取
返回列表