Skip to content

本文是视频《8种解题模式搞定80%的LeetCode算法题》(作者:Sahil & Sarra)的精读笔记,配套中配视频观看效果更佳。

8种解题模式搞定80%的LeetCode算法题 ​

这是一条仅 7 分钟的算法干货视频:原作者 Sahil & Sarra 用 8 种反复出现的解题模式,覆盖大部分 LeetCode 高频题型。最有说服力的是开篇自白——博主刷了 554 道题才悟出这套方法,而看视频的你可以直接抄近道。它不适合零基础者指望“看完就会”,但非常适合想在刷题前先建立识别地图的人。

图:视频封面:7 分钟、8 种模式,刷题方法论一图收尽

全景:一条主线看懂 ​

全片是一条“祛魅—给方法—留作业”的直线:先用“我刷了 554 道题,但你不必如此”打消题海焦虑,再把 500 多道题的复盘浓缩成 8 种可识别的模式,每种都按“定义→识别信号→例题→解法”讲透,最后留下一句行动指令——为每种模式找题逐练。必须划重点的前提:博主明说,解这些题需要对数据结构与算法(DSA)有扎实理解,模式是加速器,不是替代品。

「我做了 500 多道题才明白,提升刷题能力有个更简单的方法,那就是专注于反复出现的模式。」——博主 Sahil 在开场复盘刷题经历时说,这是全片方法论的原点。

图:金句卡片:554 道题换来的一个顿悟

#模式识别信号经典例题
1滑动窗口求“最长/最短”且满足条件的子串/子数组含 k 个不同字符的最长子串
2子集模式要枚举元素的所有组合/排列全排列
3改造版二分查找数据基本有序但被“动过手脚”搜索旋转排序数组
4Top K 元素从大数据集中选出前 k 个/第 k 大求第 k 大的数
5二叉树 DFS一条分支走到底再回头二叉树的最大深度
6拓扑排序出现“先决条件链”/依赖关系课程表
7二叉树 BFS需要按层处理节点二叉树的层序遍历
8双指针有序数组、要求高效一遍扫描两数之和 / 三数之和

图:全片主线:信号词 → 模式 → 例题的识别地图

一、面对“一串数据”:滑动窗口与子集模式 ​

滑动窗口解决“扫描不全、暴力超时”的矛盾。 它的机制很朴素:处理数组、字符串这类线性结构时,不每次看全貌,只盯住正在查看的一小段——这就是“窗口”;窗口每次向前滑一步,直到扫完整条列表。识别信号有两层:一是题目要找满足给定条件的元素子集,二是输入是数组、字符串或链表这类线性数据结构;最典型的问法是求满足条件的“最长/最短”子串或子数组,例题“含 k 个不同字符的最长子串”就是标准应用——输入是字符串,目标是找满足“不同字符”条件的最长子串。

子集模式应对“要枚举一切可能”的需求。 当题目要求找出集合中元素的所有可能组合时启用;是否允许元素重复,取决于具体题目。例题是 LeetCode“全排列”:从空集开始逐层迭代构建,每一层考虑把下一个元素以所有方式加入现有子集、生成新子集——这种逐层展开的思路,本质上和广度优先搜索(BFS)非常相似。

图:滑动窗口示意:窗口逐格右移,扫描整条列表

本节要点:看到“最长/最短子串、子数组”就上滑动窗口;看到“所有组合/排列”就上子集模式,逐层构建、类 BFS 展开。

二、在“有序与海量”里做减法:改造版二分查找与 Top K ​

二分查找的灵魂是“反复把搜索空间减半”,改造版只动逻辑、不动灵魂。 例题“搜索旋转排序数组”里,数组本有序、却在未知轴点上被旋转过,此时不能套标准二分,而要修改判断逻辑来决定搜哪一半。博主的经验之谈值得抄下来:

「真正吃透核心的二分查找算法,对我解决改造版二分查找问题帮助很大。」——Sahil 谈改造版二分查找时的个人经验。

怎么才算“吃透”?他给了一个自查标准:能在脑中想象出当数组含重复元素、或不含目标值时,左右指针最终停在哪里。配套训练法藏在 Python 的 bisect 模块里——bisect_left 和 bisect_right 两个函数,亲手用自己熟悉的语言实现一遍,对二分查找的理解会大幅提升。

Top K 模式解决“从大数据集里挑 k 个”。 识别信号是题目要求找出排名靠前的元素,输入通常是数组或列表。例题:给定数字数组,高效找出第 k 大的数。解法是持续记录“到目前为止见过的最大的 k 个数”,用堆来存——堆顶那个最小的数,就是当前的第 k 大;每来一个新数,只要它比当前第 k 大还大,就移除堆顶、把新数入堆。选堆的原因只有一个:它能非常快速地查找并移除最小数。

图:小顶堆维护“见过的最大的 k 个数”,堆顶即第 k 大

本节要点:二分先吃透标准版(脑补指针落点、手写 bisect_left/right),变体只是微调;求第 k 大就用堆维护,堆顶即答案,新数更大就换。

三、同一棵树的两种走法:DFS 与 BFS ​

二叉树 DFS:一次专注一条分支,一般用递归实现。 流程是从根节点出发,先对左节点递归应用 DFS,一路深入直到没有子节点的死路,然后回溯;若右节点存在,再转向右节点重复整个过程,直至遍历完整棵树。热门例题“二叉树的最大深度”(求根到叶节点的最长路径)解法极简:DFS 过程中记录当前深度,每当走到死路,若当前深度超过已记录的最大深度就更新——用博主的话说,“就这么简单”。

二叉树 BFS:与 DFS 完全相反,先探索同一层的所有节点。 实现上必须用队列:初始队列只含根节点,之后不断循环“从队首取出一个节点、对它执行需要的操作、把它的两个子节点加入队列”,直到队列为空。这样做的效果是同一层的节点在队列中始终彼此相邻,可以依次处理。LeetCode“二叉树的层序遍历”就是这套流程的直接应用,题意与机制一一对应。

图:同一棵树:DFS 一条道走到黑再回溯,BFS 一层一层铺开

本节要点:要“扎到底”用 DFS,递归加回溯;要“摊开来”用 BFS,队列是标配;最大深度与层序遍历分别是二者的招牌例题。

四、有依赖,就排序:拓扑排序 ​

当元素之间互为前提时,拓扑排序负责把乱序变成可执行的顺序。 它特别适用于有向无环图(DAG):节点之间的连接是单向的、且不存在环。识别信号被博主浓缩成一句口诀:

「只要有先决条件链,就想想拓扑排序。」——Sahil 在讲何时使用拓扑排序时给出的提示性口诀。

视频用软件开发场景解释原理:构建复杂程序时,某些代码依赖其他模块先被编写并测试完成,而这些模块又依赖另外的模块,层层嵌套;拓扑排序通过分析模块间的依赖关系生成一个序列,保证每个模块都在其所有前置任务完成之后才被处理。配套练习是 LeetCode“课程表”——把模块换成互为前置条件的课程,是最典型的拓扑排序应用。

图:课程先修关系图:单向连接、无环,典型的 DAG

本节要点:题目里出现“A 依赖 B、B 又依赖 C”的链条,就在 DAG 上跑拓扑排序,输出一个每步都踩在前置完成之后的执行序列。

五、有序数组的省力诀窍:双指针模式 ​

双指针的本质是用两个索引的协调移动,换一遍扫描的高效。 它适用于需要遍历有序数组的问题:两个指针各跟踪数组中的一个索引,只要移动得巧,往往一遍扫描就能解决问题。例题“两数之和”(有序版):返回两个数的索引,使二者之和等于目标和。初始化时第一个指针从数组开头出发、第二个从末尾出发;移动规则看比较结果——两数之和小于目标,左指针右移;大于目标,右指针左移。这一切成立的前提,博主点得很透:

「这么做之所以可行,是因为输入数组是有序的。」——Sahil 解释两数之和左右移动策略时强调的可行性依据。

进阶变体是“三数之和”:在有序数组中找出三个数使它们的和为零,仍然建立在同一套指针逻辑上。讲完全部八种,博主没有宣布“学完了”,而是明确交代:这里只覆盖了部分流行模式,学习任务尚未完成——你需要为每种模式找出对应的题目,逐一练习解决。

图:双指针一左一右相向夹逼,一遍扫描锁定目标和

本节要点:数组有序,才敢双指针夹逼——两数之和是模板,三数之和是变体;模式讲完只算一半,配题逐练才算闭环。

总结要点 ​

  • 方法论先于题海:博主刷了 554 道题才悟出“模式思维”,你的最优路径是在刷题前先装上这张 8 模式识别地图。
  • 背信号,不背题:最长/最短子串子数组→滑动窗口;所有组合→子集;有序但变形→改造二分;前 k 个→堆;依赖链→拓扑排序;按层处理→BFS;有序数组一遍扫→双指针。
  • 基本功决定上限:能脑补二分指针落点、能手写 bisect_left/bisect_right,比多刷几十道题更值钱。
  • 前提别跳过:没有扎实的数据结构与算法基础,模式只是记不住的咒语。
  • 闭环才算学会:每种模式配一组题逐练,把“认得出”练成“条件反射”。

迁移与启发 ​

  • 职场:先建“问题—套路”对照表,再动手。 接到任务先识别信号:多环节互为前置(如上线前要过评审、评审前要过测试)?那就是拓扑排序——先画依赖图再排期,而不是抓到哪件做哪件;被海量信息淹没?只盯“前 K 个”关键指标。第一次慢一点没关系,套路沉淀下来,第二次就是模板。
  • 投资理财:用少数模式过滤大多数决策。 不必研究完所有产品才敢下手(这正是“不必刷 554 题”的道理),掌握反复出现的核心问题即可:收益从哪来、风险谁承担、急用钱时能不能退出——三个问题筛掉八成可疑标的;看到“保本高收益”这类信号词,就该像看到“先决条件链”想到拓扑排序一样,条件反射般拉响警报。
  • 生活排障:学二分的“减半”,别学线性的“遍历”。 家里断网、身体不适、东西找不到,先排除一半可能,再对剩下一半继续二分,远比从头到尾挨个试快;做学习、考证、搬家这类多步骤计划时,先把“先决条件链”画出来,顺序对了,执行才不打结。

一句话升华 ​

题海无边,模式作舟——高手不是做完了所有题,而是一眼认出新题身上那件旧题的外衣。