From c7d9baaf5ff8735b9168a1ed6aee6409e74ef8b1 Mon Sep 17 00:00:00 2001 From: ITCharge Date: Mon, 14 Aug 2023 18:04:24 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=9B=AE=E5=BD=95=E7=AB=A0?= =?UTF-8?q?=E8=8A=82=E5=88=97=E8=A1=A8=E3=80=81=E6=9B=B4=E6=96=B0=E5=88=86?= =?UTF-8?q?=E7=B1=BB=E9=A2=98=E8=A7=A3=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/Origins/Categories-List.md | 2 +- Assets/Origins/README-Catalogue-List.md | 6 +- Contents/00.Introduction/04.Solutions-List.md | 4 +- .../00.Introduction/05.Categories-List.md | 2 +- .../01.Gaph-Minimum-Spanning-Tree.md | 73 +++++++++++++++++++ .../01.Gaph-Spanning-Tree.md | 0 ... => 02.Gaph-Minimum-Spanning-Tree-List.md} | 2 +- .../03.Gaph-Spanning-Tree/02.Graph-Prim.md | 0 .../03.Gaph-Spanning-Tree/03.Graph-Kruskal.md | 0 Contents/index.md | 6 +- README.md | 8 +- 11 files changed, 86 insertions(+), 17 deletions(-) create mode 100644 Contents/08.Graph/03.Gaph-Spanning-Tree/01.Gaph-Minimum-Spanning-Tree.md delete mode 100644 Contents/08.Graph/03.Gaph-Spanning-Tree/01.Gaph-Spanning-Tree.md rename Contents/08.Graph/03.Gaph-Spanning-Tree/{04.Gaph-Spanning-Tree-List.md => 02.Gaph-Minimum-Spanning-Tree-List.md} (96%) delete mode 100644 Contents/08.Graph/03.Gaph-Spanning-Tree/02.Graph-Prim.md delete mode 100644 Contents/08.Graph/03.Gaph-Spanning-Tree/03.Graph-Kruskal.md diff --git a/Assets/Origins/Categories-List.md b/Assets/Origins/Categories-List.md index 916a55a7..8e6988d3 100644 --- a/Assets/Origins/Categories-List.md +++ b/Assets/Origins/Categories-List.md @@ -203,7 +203,7 @@ ###### 0207. 课程表、0210. 课程表 II、1136. 并行课程、2050. 并行课程 III、0802. 找到最终的安全状态、0851. 喧闹和富有 -### [图的生成树题目](../../Contents/08.Graph/03.Gaph-Spanning-Tree/04.Gaph-Spanning-Tree-List.md) +### [图的最小生成树题目](../../Contents/08.Graph/03.Gaph-Spanning-Tree/02.Gaph-Minimum-Spanning-Tree-List.md) ###### 1584. 连接所有点的最小费用、1631. 最小体力消耗路径、0778. 水位上升的泳池中游泳 diff --git a/Assets/Origins/README-Catalogue-List.md b/Assets/Origins/README-Catalogue-List.md index 9675aaa7..36ee9fb8 100644 --- a/Assets/Origins/README-Catalogue-List.md +++ b/Assets/Origins/README-Catalogue-List.md @@ -128,10 +128,8 @@ - [图的拓扑排序知识](https://github.com/itcharge/LeetCode-Py/blob/main/Contents/08.Graph/02.Graph-Traversal/05.Graph-Topological-Sorting.md) - [图的拓扑排序题目](https://github.com/itcharge/LeetCode-Py/blob/main/Contents/08.Graph/02.Graph-Traversal/06.Graph-Topological-Sorting-List.md) - 图的生成树 - - [图的生成树知识](https://github.com/itcharge/LeetCode-Py/blob/main/Contents/08.Graph/03.Gaph-Spanning-Tree/01.Gaph-Spanning-Tree.md) - - [Prim 算法](https://github.com/itcharge/LeetCode-Py/blob/main/Contents/08.Graph/03.Gaph-Spanning-Tree/02.Graph-Prim.md) - - [Kruskal 算法](https://github.com/itcharge/LeetCode-Py/blob/main/Contents/08.Graph/03.Gaph-Spanning-Tree/03.Graph-Kruskal.md) - - [图的生成树题目](https://github.com/itcharge/LeetCode-Py/blob/main/Contents/08.Graph/03.Gaph-Spanning-Tree/04.Gaph-Spanning-Tree-List.md) + - [图的最小生成树](https://github.com/itcharge/LeetCode-Py/blob/main/Contents/08.Graph/03.Gaph-Spanning-Tree/01.Gaph-Minimum-Spanning-Tree.md) + - [图的最小生成树题目](https://github.com/itcharge/LeetCode-Py/blob/main/Contents/08.Graph/03.Gaph-Spanning-Tree/02.Gaph-Minimum-Spanning-Tree-List.md) - 最短路径 - [单源最短路径知识](https://github.com/itcharge/LeetCode-Py/blob/main/Contents/08.Graph/04.Graph-Shortest-Path/01.Graph-Single-Source-Shortest-Path.md) - [Dijkstra 算法](https://github.com/itcharge/LeetCode-Py/blob/main/Contents/08.Graph/04.Graph-Shortest-Path/02.Graph-Dijkstra.md) diff --git a/Contents/00.Introduction/04.Solutions-List.md b/Contents/00.Introduction/04.Solutions-List.md index f7946b53..f2f33c1a 100644 --- a/Contents/00.Introduction/04.Solutions-List.md +++ b/Contents/00.Introduction/04.Solutions-List.md @@ -1,4 +1,4 @@ -# LeetCode 题解(已完成 821 道) +# LeetCode 题解(已完成 823 道) | 题号 | 标题 | 题解 | 标签 | 难度 | | :------ | :------ | :------ | :------ | :------ | @@ -424,6 +424,7 @@ | 0801 | [使序列递增的最小交换次数](https://leetcode.cn/problems/minimum-swaps-to-make-sequences-increasing/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/0801.%20%E4%BD%BF%E5%BA%8F%E5%88%97%E9%80%92%E5%A2%9E%E7%9A%84%E6%9C%80%E5%B0%8F%E4%BA%A4%E6%8D%A2%E6%AC%A1%E6%95%B0.md) | 数组、动态规划 | 困难 | | 0802 | [找到最终的安全状态](https://leetcode.cn/problems/find-eventual-safe-states/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/0802.%20%E6%89%BE%E5%88%B0%E6%9C%80%E7%BB%88%E7%9A%84%E5%AE%89%E5%85%A8%E7%8A%B6%E6%80%81.md) | 深度优先搜索、广度优先搜索、图、拓扑排序 | 中等 | | 0803 | [打砖块](https://leetcode.cn/problems/bricks-falling-when-hit/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/0803.%20%E6%89%93%E7%A0%96%E5%9D%97.md) | 并查集、数组、矩阵 | 困难 | +| 0806 | [写字符串需要的行数](https://leetcode.cn/problems/number-of-lines-to-write-string/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/0806.%20%E5%86%99%E5%AD%97%E7%AC%A6%E4%B8%B2%E9%9C%80%E8%A6%81%E7%9A%84%E8%A1%8C%E6%95%B0.md) | 数组、字符串 | 简单 | | 0811 | [子域名访问计数](https://leetcode.cn/problems/subdomain-visit-count/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/0811.%20%E5%AD%90%E5%9F%9F%E5%90%8D%E8%AE%BF%E9%97%AE%E8%AE%A1%E6%95%B0.md) | 数组、哈希表、字符串、计数 | 中等 | | 0814 | [二叉树剪枝](https://leetcode.cn/problems/binary-tree-pruning/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/0814.%20%E4%BA%8C%E5%8F%89%E6%A0%91%E5%89%AA%E6%9E%9D.md) | 树、深度优先搜索、二叉树 | 中等 | | 0819 | [最常见的单词](https://leetcode.cn/problems/most-common-word/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/0819.%20%E6%9C%80%E5%B8%B8%E8%A7%81%E7%9A%84%E5%8D%95%E8%AF%8D.md) | 哈希表、字符串、计数 | 简单 | @@ -608,6 +609,7 @@ | 1941 | [检查是否所有字符出现次数相同](https://leetcode.cn/problems/check-if-all-characters-have-equal-number-of-occurrences/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1941.%20%E6%A3%80%E6%9F%A5%E6%98%AF%E5%90%A6%E6%89%80%E6%9C%89%E5%AD%97%E7%AC%A6%E5%87%BA%E7%8E%B0%E6%AC%A1%E6%95%B0%E7%9B%B8%E5%90%8C.md) | 哈希表、字符串、计数 | 简单 | | 1947 | [最大兼容性评分和](https://leetcode.cn/problems/maximum-compatibility-score-sum/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1947.%20%E6%9C%80%E5%A4%A7%E5%85%BC%E5%AE%B9%E6%80%A7%E8%AF%84%E5%88%86%E5%92%8C.md) | 位运算、数组、动态规划、回溯、状态压缩 | 中等 | | 1986 | [完成任务的最少工作时间段](https://leetcode.cn/problems/minimum-number-of-work-sessions-to-finish-the-tasks/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1986.%20%E5%AE%8C%E6%88%90%E4%BB%BB%E5%8A%A1%E7%9A%84%E6%9C%80%E5%B0%91%E5%B7%A5%E4%BD%9C%E6%97%B6%E9%97%B4%E6%AE%B5.md) | 位运算、数组、动态规划、回溯、状态压缩 | 中等 | +| 1991 | [找到数组的中间位置](https://leetcode.cn/problems/find-the-middle-index-in-array/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1991.%20%E6%89%BE%E5%88%B0%E6%95%B0%E7%BB%84%E7%9A%84%E4%B8%AD%E9%97%B4%E4%BD%8D%E7%BD%AE.md) | 数组、前缀和 | 简单 | | 1994 | [好子集的数目](https://leetcode.cn/problems/the-number-of-good-subsets/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1994.%20%E5%A5%BD%E5%AD%90%E9%9B%86%E7%9A%84%E6%95%B0%E7%9B%AE.md) | 位运算、数组、数学、动态规划、状态压缩 | 困难 | | 2011 | [执行操作后的变量值](https://leetcode.cn/problems/final-value-of-variable-after-performing-operations/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/2011.%20%E6%89%A7%E8%A1%8C%E6%93%8D%E4%BD%9C%E5%90%8E%E7%9A%84%E5%8F%98%E9%87%8F%E5%80%BC.md) | 数组、字符串、模拟 | 简单 | | 2023 | [连接后等于目标字符串的字符串对](https://leetcode.cn/problems/number-of-pairs-of-strings-with-concatenation-equal-to-target/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/2023.%20%E8%BF%9E%E6%8E%A5%E5%90%8E%E7%AD%89%E4%BA%8E%E7%9B%AE%E6%A0%87%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%AF%B9.md) | 数组、字符串 | 中等 | diff --git a/Contents/00.Introduction/05.Categories-List.md b/Contents/00.Introduction/05.Categories-List.md index 8648025d..fe80ab24 100644 --- a/Contents/00.Introduction/05.Categories-List.md +++ b/Contents/00.Introduction/05.Categories-List.md @@ -646,7 +646,7 @@ | 0802 | [找到最终的安全状态](https://leetcode.cn/problems/find-eventual-safe-states/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/0802.%20%E6%89%BE%E5%88%B0%E6%9C%80%E7%BB%88%E7%9A%84%E5%AE%89%E5%85%A8%E7%8A%B6%E6%80%81.md) | 深度优先搜索、广度优先搜索、图、拓扑排序 | 中等 | | 0851 | [喧闹和富有](https://leetcode.cn/problems/loud-and-rich/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/0851.%20%E5%96%A7%E9%97%B9%E5%92%8C%E5%AF%8C%E6%9C%89.md) | 深度优先搜索、图、拓扑排序、数组 | 中等 | -### 图的生成树题目 +### 图的最小生成树题目 | 题号 | 标题 | 题解 | 标签 | 难度 | | :------ | :------ | :------ | :------ | :------ | diff --git a/Contents/08.Graph/03.Gaph-Spanning-Tree/01.Gaph-Minimum-Spanning-Tree.md b/Contents/08.Graph/03.Gaph-Spanning-Tree/01.Gaph-Minimum-Spanning-Tree.md new file mode 100644 index 00000000..83fdacfb --- /dev/null +++ b/Contents/08.Graph/03.Gaph-Spanning-Tree/01.Gaph-Minimum-Spanning-Tree.md @@ -0,0 +1,73 @@ +## 1. 最小生成树的定义 + +在了解「最小生成树」之前,我们需要要先理解 「生成树」的概念。 + +> **图的生成树(Spanning Tree)**:如果无向连通图 G 的一个子图是一棵包含图 G 所有顶点的树,则称该子图为 G 的生成树。生成树是连通图的包含图中的所有顶点的极小连通子图。图的生成树不惟一。从不同的顶点出发进行遍历,可以得到不同的生成树。 + +换句话说,生成树是原图 G 的一个子图,它包含了原图 G 的所有顶点,并且通过选择图中一部分边连接这些顶点,使得子图中没有环。 + +生成树有以下特点: + +1. **包含所有顶点**:生成树中包含了原图的所有顶点。 +2. **连通性**:生成树是原图的一个连通子图,意味着任意两个顶点之间都存在一条路径。 +3. **无环图**:生成树一个无环图。 +4. **边数最少**:在包含所有顶点的情况下,生成树的边数最少,其边数为顶点数减 $1$。 + +> **最小生成树(Minimum Spanning Tree)**:无向连通图 G 的所有生成树中,边的权值之和最小的生成树,被称为最小生成树。 + +最小生成树除了包含生成树的特点之外,还具有一个特点。 + +1. **边的权值之和最小**:在包含所有顶点的情况下,最小生成树的边的权重之和是所有可能的生成树中最小的。 + +为了找到无向图的最小生成树,常用的算法有「Prim 算法」和「Kruskal 算法」。 + +- **Prim 算法**:从一个起始顶点出发,逐步选择与已经构建的树连接的最短边,直到包含所有顶点为止。 +- **Kruskal 算法**:基于边的排序和并查集数据结构,逐步添加边,并保证所选边不会构成环路,直到构建出最小生成树。 + +这两个算法都可以帮助我们找到图中的最小生成树,以满足连接所有顶点的要求同时使得总权重最小。 + +## 2. Prim 算法 + +### 2.1 Prim 算法的算法思想 + +> **Prim 算法的算法思想**:每次选择最短边来扩展最小生成树,从而保证生成树的总权重最小。算法通过不断扩展小生成树的顶点集合 $MST$,逐步构建出最小生成树。 + +### 2.2 Prim 算法的实现步骤 + +1. 维护两个集合,一个是已经加入到最小生成树的顶点集合 $MST$,另一个是还未加入生成树的顶点集合。 +2. 选择起始顶点,将其加入到最小生成树的顶点集合 $MST$ 中。 +3. 从 $MST$ 的顶点集合中选择一个顶点,然后找到连接这个顶点与 $MST$ 之间的边中权重最小的边。 +4. 让上一步中找到的顶点和边加入到 $MST$ 中,更新 $MST$ 的顶点集合和边集合。 +5. 重复第 $3 \sim 4$ 步,直到 $MST$ 的顶点集合中包含了图中的所有顶点为止。 + +### 2.3 Prim 算法的实现代码 + +```Python + +``` + +### 2.3 Prim 算法 + +## 03. Kruskal 算法 + +### 3.1 Kruskal 算法的算法思想 + +> **Kruskal 算法的算法思想**:通过依次选择权重最小的边并判断其两个端点是否连接在同一集合中,从而逐步构建最小生成树。这个过程保证了最终生成的树是无环的,并且总权重最小。 + +在实际实现中,我们通常使用并查集数据结构来管理顶点的集合信息,以便高效地判断两个顶点是否在同一个集合中,以及合并集合。 + +### 3.2 Kruskal 算法的实现步骤 + +1. 将图中所有边按照权重从小到大进行排序。 +2. 将每个顶点看做是一个单独集合,即初始时每个顶点自成一个集合。 +3. 按照排好序的边顺序,按照权重从小到大,依次遍历每一条边。 +4. 对于每条边,检查其连接的两个顶点所属的集合: + 1. 如果两个顶点属于同一个集合,则跳过这条边,以免形成环路。 + 2. 如果两个顶点不属于同一个集合,则将这条边加入到最小生成树中,同时合并这两个顶点所属的集合。 +5. 重复第 $3 \sim 4$ 步,直到最小生成树中的变数等于所有节点数减 $1$ 为止。 + +### 3.3 Kruskal 算法的实现代码 + +```Python + +``` \ No newline at end of file diff --git a/Contents/08.Graph/03.Gaph-Spanning-Tree/01.Gaph-Spanning-Tree.md b/Contents/08.Graph/03.Gaph-Spanning-Tree/01.Gaph-Spanning-Tree.md deleted file mode 100644 index e69de29b..00000000 diff --git a/Contents/08.Graph/03.Gaph-Spanning-Tree/04.Gaph-Spanning-Tree-List.md b/Contents/08.Graph/03.Gaph-Spanning-Tree/02.Gaph-Minimum-Spanning-Tree-List.md similarity index 96% rename from Contents/08.Graph/03.Gaph-Spanning-Tree/04.Gaph-Spanning-Tree-List.md rename to Contents/08.Graph/03.Gaph-Spanning-Tree/02.Gaph-Minimum-Spanning-Tree-List.md index 2a9941bf..e3e7ab31 100644 --- a/Contents/08.Graph/03.Gaph-Spanning-Tree/04.Gaph-Spanning-Tree-List.md +++ b/Contents/08.Graph/03.Gaph-Spanning-Tree/02.Gaph-Minimum-Spanning-Tree-List.md @@ -1,4 +1,4 @@ -### 图的生成树题目 +### 图的最小生成树题目 | 题号 | 标题 | 题解 | 标签 | 难度 | | :------ | :------ | :------ | :------ | :------ | diff --git a/Contents/08.Graph/03.Gaph-Spanning-Tree/02.Graph-Prim.md b/Contents/08.Graph/03.Gaph-Spanning-Tree/02.Graph-Prim.md deleted file mode 100644 index e69de29b..00000000 diff --git a/Contents/08.Graph/03.Gaph-Spanning-Tree/03.Graph-Kruskal.md b/Contents/08.Graph/03.Gaph-Spanning-Tree/03.Graph-Kruskal.md deleted file mode 100644 index e69de29b..00000000 diff --git a/Contents/index.md b/Contents/index.md index d4af4de9..6e8e9763 100644 --- a/Contents/index.md +++ b/Contents/index.md @@ -130,10 +130,8 @@ - [图的拓扑排序知识](./08.Graph/02.Graph-Traversal/05.Graph-Topological-Sorting.md) - [图的拓扑排序题目](./08.Graph/02.Graph-Traversal/06.Graph-Topological-Sorting-List.md) - 图的生成树 - - [图的生成树知识](./08.Graph/03.Gaph-Spanning-Tree/01.Gaph-Spanning-Tree.md) - - [Prim 算法](./08.Graph/03.Gaph-Spanning-Tree/02.Graph-Prim.md) - - [Kruskal 算法](./08.Graph/03.Gaph-Spanning-Tree/03.Graph-Kruskal.md) - - [图的生成树题目](./08.Graph/03.Gaph-Spanning-Tree/04.Gaph-Spanning-Tree-List.md) + - [图的最小生成树](./08.Graph/03.Gaph-Spanning-Tree/01.Gaph-Minimum-Spanning-Tree.md) + - [图的最小生成树题目](./08.Graph/03.Gaph-Spanning-Tree/02.Gaph-Minimum-Spanning-Tree-List.md) - 最短路径 - [单源最短路径知识](./08.Graph/04.Graph-Shortest-Path/01.Graph-Single-Source-Shortest-Path.md) - [Dijkstra 算法](./08.Graph/04.Graph-Shortest-Path/02.Graph-Dijkstra.md) diff --git a/README.md b/README.md index e9bbf479..541e36e2 100644 --- a/README.md +++ b/README.md @@ -169,10 +169,8 @@ - [图的拓扑排序知识](./Contents/08.Graph/02.Graph-Traversal/05.Graph-Topological-Sorting.md) - [图的拓扑排序题目](./Contents/08.Graph/02.Graph-Traversal/06.Graph-Topological-Sorting-List.md) - 图的生成树 - - [图的生成树知识](./Contents/08.Graph/03.Gaph-Spanning-Tree/01.Gaph-Spanning-Tree.md) - - [Prim 算法](./Contents/08.Graph/03.Gaph-Spanning-Tree/02.Graph-Prim.md) - - [Kruskal 算法](./Contents/08.Graph/03.Gaph-Spanning-Tree/03.Graph-Kruskal.md) - - [图的生成树题目](./Contents/08.Graph/03.Gaph-Spanning-Tree/04.Gaph-Spanning-Tree-List.md) + - [图的最小生成树](./Contents/08.Graph/03.Gaph-Spanning-Tree/01.Gaph-Minimum-Spanning-Tree.md) + - [图的最小生成树题目](./Contents/08.Graph/03.Gaph-Spanning-Tree/02.Gaph-Minimum-Spanning-Tree-List.md) - 最短路径 - [单源最短路径知识](./Contents/08.Graph/04.Graph-Shortest-Path/01.Graph-Single-Source-Shortest-Path.md) - [Dijkstra 算法](./Contents/08.Graph/04.Graph-Shortest-Path/02.Graph-Dijkstra.md) @@ -259,4 +257,4 @@ - [动态规划优化题目](./Contents/10.Dynamic-Programming/11.DP-Optimization/04.DP-Optimization-List.md) ## 11. 附加内容 -## [12. LeetCode 题解(已完成 821 道)](./Contents/00.Introduction/04.Solutions-List.md) \ No newline at end of file +## [12. LeetCode 题解(已完成 823 道)](./Contents/00.Introduction/04.Solutions-List.md) \ No newline at end of file