【学会这8个模式可以解决80%的Leetcode问题】https://www.bilibili.com/video/BV16Z421T7Ax
印度阿三的视频质量很高
视频文案翻译润色
我已经解决了554道LeetCode题目,但你不必这样做。我花了500多道题才意识到,有一种更简单的方法可以提高解决编程问题的能力,那就是专注于反复出现的模式。在这个视频中,我将向你展示8种这样的模式。
让我们从滑动窗口模式开始。滑动窗口模式用于处理一系列数据元素,比如列表或字符串。在滑动窗口模式中,你通过一次查看列表的一小部分来找到特定的东西。你正在查看的列表部分称为你的窗口。这个窗口然后一次滑动一步,直到整个列表被扫描完毕。
什么时候使用滑动窗口模式呢?如果一个问题要求你找到满足给定条件的元素子集,就考虑使用滑动窗口模式。你的输入将是一个线性数据结构,如数组、字符串或链表,你需要找到满足特定条件的最长或最短子串或子数组。
例如,看看这个"具有K个唯一字符的最长子串"问题。你的输入是一个字符串,你需要找到满足唯一字符条件的最长子串。这是一个经典的滑动窗口问题。
接下来我们有子集模式。子集模式用于从给定集合中找出所有可能的元素组合。根据问题的不同,可能允许或不允许重复。在子集模式中,我们需要探索给定集合中所有可能的元素排列。
以LeetCode上的排列问题为例。要解决这个问题,你可以逐级迭代地构建所有子集。从一个空集开始,在每一级考虑所有将下一个元素添加到现有子集的方法,并创建一个新的子集。这种方法非常类似于广度优先搜索或BFS。
接下来是修改后的二分搜索模式。二分搜索的核心思想是不断地将搜索空间一分为二。在修改后的二分搜索模式中,核心思想保持不变,但我们需要稍微调整逻辑以解决给定的问题。
让我们以"搜索旋转排序数组"问题为例。在这里,数组是排序的,但在一个未知的枢轴点旋转了。你需要修改标准的二分搜索,以确定在数组的哪一半进行搜索。
在解决修改后的二分搜索问题时,对我帮助很大的一件事是真正理解核心二分搜索算法。对于核心二分搜索算法,你需要能够可视化左右指针在数组包含重复项或数组不包含目标时的最终位置。
让我给你一个提高二分搜索可视化能力的好方法。Python中的bisect模块包含两个函数:bisect_left和bisect_right。用你选择的语言实现这两个函数,你对二分搜索的理解将会大大提高。
接下来我们要讨论的模式是Top K元素模式。Top K元素模式用于从较大的数据集中选择K个元素,给定特定条件。当问题要求你从数据集中找出排名靠前的元素时,就考虑使用这种模式。输入通常是线性数据结构,如数组或列表。
例如,给定一个数字数组,你需要高效地找到第K大的数字。要解决这个问题,你需要跟踪到目前为止见过的K个最重要的数字。由于你关心的是第K大的元素,所以你到目前为止见过的最大的K个元素是最重要的。因此,你会使用一种叫做堆的数据结构来存储它们。
我们稍后会回来讨论为什么使用堆。无论如何,堆上的最小数字将是我们到目前为止见过的第K大的数字。如果新数字大于目前为止的第K大数字,你将移除目前为止的第K大数字,并将新数字添加到堆中。我们在这里使用堆,是因为它使找到和移除最小数字变得非常高效。
接下来我们有**二叉树的深度优先搜索(DFS)**模式。二叉树DFS帮助你访问树上的每个节点,一次专注于一个分支。通常,你会使用递归来完成这个任务。
这是流程的样子:你将从根节点开始。之后,你递归地对左节点应用DFS。这个过程继续深入左子树,直到到达没有子节点的节点。一旦DFS在左侧到达死胡同,它就会回溯。现在它关注右节点(如果存在),并再次递归地应用DFS。通过这样做,你探索整个右子树。
例如,在这个非常流行的"二叉树的最大深度"问题中,你需要找到从根节点到叶节点的最长路径的长度。为此,你只需在进行二叉树DFS时跟踪深度,每当到达死胡同时,如果当前深度大于最大深度,就更新最大深度。就这么简单。
列表中的下一个模式是拓扑排序。拓扑排序用于在元素之间存在依赖关系时以特定顺序排列元素。它特别适用于有向无环图。当图的节点之间有单向连接且没有循环时,它被称为有向无环图。
每当你有一个先决条件链时,就考虑使用拓扑排序。让我解释一下我的意思。想象你正在构建一个复杂的程序。代码的某些部分可能依赖于其他模块的编写和测试,而这些模块又可能依赖于其他模块。拓扑排序可以通过分析不同模块之间的依赖关系,帮助你确定应该以什么顺序编写模块。它创建一个序列,其中每个模块只有在其所有先决条件都完成后才会被处理。
尝试在LeetCode上解决这个"课程表"问题,其中我们有作为其他课程先决条件的课程,而不是模块。
接下来我们有**二叉树的广度优先搜索(BFS)**模式。我们已经讨论过二叉树DFS。在二叉树DFS中,我们深入一个分支并完全探索它,然后移动到其他分支。在二叉树BFS中,我们采用不同的方法。BFS首先探索不同分支中处于同一层级的所有节点。
要做到这一点,你需要使用队列数据结构。一开始,队列只包含根节点。之后,你将重复我要向你展示的过程。你从队列前面移除一个节点,并对其进行任何你想进行的操作。然后你将其两个子节点都添加到队列中。你一直这样做,直到队列为空。
通过这样做,树中同一层级的元素将始终在队列中彼此相邻。这样你就可以一个接一个地处理它们。这种模式的直接应用是一个叫做"二叉树的层序遍历"的问题。它正是我刚刚解释的内容。
最后,我们有双指针模式。双指针模式用于解决需要遍历排序数组的问题。顾名思义,我们将在这种模式中使用两个指针。每个指针将跟踪数组中的一个索引。通过智能地移动这些指针,我们通常可以在一次遍历中解决问题,使算法更加高效。
让我们以"两数之和"问题为例。给你一个排序数组,你需要返回两个数字的索引,这两个数字加起来等于目标和。要解决这个问题,你可以使用两个指针。第一个指针从开头开始,第二个指针从数组末尾开始。根据指针所指数字之和是小于还是大于目标和,你要么将左指针向右移动,要么将右指针向左移动。这种方法之所以有效,是因为输入数组是排序的。
同一问题的另一种变体是,当你需要在排序数组中找到加起来等于零的三元组时。