Skip to content

Commit 031da1e

Browse files
committed
更新题解列表
1 parent ff355e7 commit 031da1e

File tree

7 files changed

+233
-6
lines changed

7 files changed

+233
-6
lines changed

Contents/00.Introduction/04.Solutions-List.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# LeetCode 题解(已完成 859 道)
1+
# LeetCode 题解(已完成 860 道)
22

33
| 题号 | 标题 | 题解 | 标签 | 难度 |
44
| :------ | :------ | :------ | :------ | :------ |
@@ -598,6 +598,7 @@
598598
| 1561 | [你可以获得的最大硬币数目](https://leetcode.cn/problems/maximum-number-of-coins-you-can-get/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1561.%20%E4%BD%A0%E5%8F%AF%E4%BB%A5%E8%8E%B7%E5%BE%97%E7%9A%84%E6%9C%80%E5%A4%A7%E7%A1%AC%E5%B8%81%E6%95%B0%E7%9B%AE.md) | 贪心、数组、数学、博弈、排序 | 中等 |
599599
| 1567 | [乘积为正数的最长子数组长度](https://leetcode.cn/problems/maximum-length-of-subarray-with-positive-product/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1567.%20%E4%B9%98%E7%A7%AF%E4%B8%BA%E6%AD%A3%E6%95%B0%E7%9A%84%E6%9C%80%E9%95%BF%E5%AD%90%E6%95%B0%E7%BB%84%E9%95%BF%E5%BA%A6.md) | 贪心、数组、动态规划 | 中等 |
600600
| 1582 | [二进制矩阵中的特殊位置](https://leetcode.cn/problems/special-positions-in-a-binary-matrix/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1582.%20%E4%BA%8C%E8%BF%9B%E5%88%B6%E7%9F%A9%E9%98%B5%E4%B8%AD%E7%9A%84%E7%89%B9%E6%AE%8A%E4%BD%8D%E7%BD%AE.md) | 数组、矩阵 | 简单 |
601+
| 1584 | [连接所有点的最小费用](https://leetcode.cn/problems/min-cost-to-connect-all-points/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1584.%20%E8%BF%9E%E6%8E%A5%E6%89%80%E6%9C%89%E7%82%B9%E7%9A%84%E6%9C%80%E5%B0%8F%E8%B4%B9%E7%94%A8.md) | 并查集、图、数组、最小生成树 | 中等 |
601602
| 1593 | [拆分字符串使唯一子字符串的数目最大](https://leetcode.cn/problems/split-a-string-into-the-max-number-of-unique-substrings/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1593.%20%E6%8B%86%E5%88%86%E5%AD%97%E7%AC%A6%E4%B8%B2%E4%BD%BF%E5%94%AF%E4%B8%80%E5%AD%90%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84%E6%95%B0%E7%9B%AE%E6%9C%80%E5%A4%A7.md) | 哈希表、字符串、回溯 | 中等 |
602603
| 1595 | [连通两组点的最小成本](https://leetcode.cn/problems/minimum-cost-to-connect-two-groups-of-points/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1595.%20%E8%BF%9E%E9%80%9A%E4%B8%A4%E7%BB%84%E7%82%B9%E7%9A%84%E6%9C%80%E5%B0%8F%E6%88%90%E6%9C%AC.md) | 位运算、数组、动态规划、状态压缩、矩阵 | 困难 |
603604
| 1603 | [设计停车系统](https://leetcode.cn/problems/design-parking-system/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1603.%20%E8%AE%BE%E8%AE%A1%E5%81%9C%E8%BD%A6%E7%B3%BB%E7%BB%9F.md) | 设计、计数、模拟 | 简单 |

Contents/00.Introduction/05.Categories-List.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -649,7 +649,7 @@
649649

650650
| 题号 | 标题 | 题解 | 标签 | 难度 |
651651
| :------ | :------ | :------ | :------ | :------ |
652-
| 1584 | [连接所有点的最小费用](https://leetcode.cn/problems/min-cost-to-connect-all-points/) | | 并查集、图、数组、最小生成树 | 中等 |
652+
| 1584 | [连接所有点的最小费用](https://leetcode.cn/problems/min-cost-to-connect-all-points/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1584.%20%E8%BF%9E%E6%8E%A5%E6%89%80%E6%9C%89%E7%82%B9%E7%9A%84%E6%9C%80%E5%B0%8F%E8%B4%B9%E7%94%A8.md) | 并查集、图、数组、最小生成树 | 中等 |
653653
| 1631 | [最小体力消耗路径](https://leetcode.cn/problems/path-with-minimum-effort/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1631.%20%E6%9C%80%E5%B0%8F%E4%BD%93%E5%8A%9B%E6%B6%88%E8%80%97%E8%B7%AF%E5%BE%84.md) | 深度优先搜索、广度优先搜索、并查集、数组、二分查找、矩阵、堆(优先队列) | 中等 |
654654
| 0778 | [水位上升的泳池中游泳](https://leetcode.cn/problems/swim-in-rising-water/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/0778.%20%E6%B0%B4%E4%BD%8D%E4%B8%8A%E5%8D%87%E7%9A%84%E6%B3%B3%E6%B1%A0%E4%B8%AD%E6%B8%B8%E6%B3%B3.md) | 深度优先搜索、广度优先搜索、并查集、数组、二分查找、矩阵、堆(优先队列) | 困难 |
655655

Contents/08.Graph/03.Graph-Spanning-Tree/02.Graph-Minimum-Spanning-Tree-List.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
| 题号 | 标题 | 题解 | 标签 | 难度 |
44
| :------ | :------ | :------ | :------ | :------ |
5-
| 1584 | [连接所有点的最小费用](https://leetcode.cn/problems/min-cost-to-connect-all-points/) | | 并查集、图、数组、最小生成树 | 中等 |
5+
| 1584 | [连接所有点的最小费用](https://leetcode.cn/problems/min-cost-to-connect-all-points/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1584.%20%E8%BF%9E%E6%8E%A5%E6%89%80%E6%9C%89%E7%82%B9%E7%9A%84%E6%9C%80%E5%B0%8F%E8%B4%B9%E7%94%A8.md) | 并查集、图、数组、最小生成树 | 中等 |
66
| 1631 | [最小体力消耗路径](https://leetcode.cn/problems/path-with-minimum-effort/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1631.%20%E6%9C%80%E5%B0%8F%E4%BD%93%E5%8A%9B%E6%B6%88%E8%80%97%E8%B7%AF%E5%BE%84.md) | 深度优先搜索、广度优先搜索、并查集、数组、二分查找、矩阵、堆(优先队列) | 中等 |
77
| 0778 | [水位上升的泳池中游泳](https://leetcode.cn/problems/swim-in-rising-water/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/0778.%20%E6%B0%B4%E4%BD%8D%E4%B8%8A%E5%8D%87%E7%9A%84%E6%B3%B3%E6%B1%A0%E4%B8%AD%E6%B8%B8%E6%B3%B3.md) | 深度优先搜索、广度优先搜索、并查集、数组、二分查找、矩阵、堆(优先队列) | 困难 |
88

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,4 +259,4 @@
259259
### 11. 附加内容
260260

261261
- [内容完成时间线](./Contents/Others/Update-Time.md)
262-
### [12. LeetCode 题解(已完成 859 道)](./Contents/00.Introduction/04.Solutions-List.md)
262+
### [12. LeetCode 题解(已完成 860 道)](./Contents/00.Introduction/04.Solutions-List.md)
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
# [1584. 连接所有点的最小费用](https://leetcode.cn/problems/min-cost-to-connect-all-points/)
2+
3+
- 标签:并查集、图、数组、最小生成树
4+
- 难度:中等
5+
6+
## 题目链接
7+
8+
- [1584. 连接所有点的最小费用 - 力扣](https://leetcode.cn/problems/min-cost-to-connect-all-points/)
9+
10+
## 题目大意
11+
12+
**描述**:给定一个 $points$ 数组,表示 2D 平面上的一些点,其中 $points[i] = [x_i, y_i]$。
13+
14+
链接点 $[x_i, y_i]$ 和点 $[x_j, y_j]$ 的费用为它们之间的 **曼哈顿距离**:$|x_i - x_j| + |y_i - y_j|$。其中 $|val|$ 表示 $val$ 的绝对值。
15+
16+
**要求**:返回将所有点连接的最小总费用。
17+
18+
**说明**
19+
20+
- 只有任意两点之间有且仅有一条简单路径时,才认为所有点都已连接。
21+
- $1 \le points.length \le 1000$。
22+
- $-10^6 \le x_i, y_i \le 10^6$。
23+
- 所有点 $(x_i, y_i)$ 两两不同。
24+
25+
**示例**
26+
27+
- 示例 1:
28+
29+
![](https://assets.leetcode.com/uploads/2020/08/26/d.png)
30+
31+
![](https://assets.leetcode.com/uploads/2020/08/26/c.png)
32+
33+
```python
34+
输入:points = [[0,0],[2,2],[3,10],[5,2],[7,0]]
35+
输出:20
36+
解释:我们可以按照上图所示连接所有点得到最小总费用,总费用为 20
37+
注意到任意两个点之间只有唯一一条路径互相到达。
38+
```
39+
40+
- 示例 2:
41+
42+
```python
43+
输入:points = [[3,12],[-2,5],[-4,1]]
44+
输出:18
45+
```
46+
47+
## 解题思路
48+
49+
将所有点之间的费用看作是边,则所有点和边可以看作是一个无向图。每两个点之间都存在一条无向边,边的权重为两个点之间的曼哈顿距离。将所有点连接的最小总费用,其实就是求无向图的最小生成树。对此我们可以使用 Prim 算法或者 Kruskal 算法。
50+
51+
### 思路 1:Prim 算法
52+
53+
每次选择最短边来扩展最小生成树,从而保证生成树的总权重最小。算法通过不断扩展小生成树的顶点集合 $MST$,逐步构建出最小生成树。
54+
55+
### 思路 1:代码
56+
57+
```Python
58+
class Solution:
59+
def distance(self, point1, point2):
60+
return abs(point1[0] - point2[0]) + abs(point1[1] - point2[1])
61+
62+
def Prim(self, points, start):
63+
size = len(points)
64+
vis = set()
65+
dis = [float('inf') for _ in range(size)]
66+
67+
ans = 0 # 最小生成树的边权值
68+
dis[start] = 0 # 起始位置到起始位置的边权值初始化为 0
69+
70+
for i in range(1, size):
71+
dis[i] = self.distance(points[start], points[i])
72+
vis.add(start)
73+
74+
for _ in range(size - 1): # 进行 n 轮迭代
75+
min_dis = float('inf')
76+
min_dis_i = -1
77+
for i in range(size):
78+
if i not in vis and dis[i] < min_dis:
79+
min_dis = dis[i]
80+
min_dis_i = i
81+
if min_dis_i == -1:
82+
return -1
83+
84+
ans += min_dis
85+
vis.add(min_dis_i)
86+
87+
88+
for i in range(size):
89+
if i not in vis:
90+
dis[i] = min(dis[i], self.distance(points[i], points[min_dis_i]))
91+
92+
return ans
93+
94+
def minCostConnectPoints(self, points: List[List[int]]) -> int:
95+
return self.Prim(points, 0)
96+
```
97+
98+
### 思路 1:复杂度分析
99+
100+
- **时间复杂度**:$O(n^2)$。
101+
- **空间复杂度**:$O(n^2)$。
102+
103+
### 思路 2:Kruskal 算法
104+
105+
通过依次选择权重最小的边并判断其两个端点是否连接在同一集合中,从而逐步构建最小生成树。这个过程保证了最终生成的树是无环的,并且总权重最小。
106+
107+
### 思路 2:代码
108+
109+
```python
110+
class UnionFind:
111+
112+
def __init__(self, n):
113+
self.parent = [i for i in range(n)]
114+
self.count = n
115+
116+
def find(self, x):
117+
while x != self.parent[x]:
118+
self.parent[x] = self.parent[self.parent[x]]
119+
x = self.parent[x]
120+
return x
121+
122+
def union(self, x, y):
123+
root_x = self.find(x)
124+
root_y = self.find(y)
125+
if root_x == root_y:
126+
return
127+
128+
self.parent[root_x] = root_y
129+
self.count -= 1
130+
131+
def is_connected(self, x, y):
132+
return self.find(x) == self.find(y)
133+
134+
135+
class Solution:
136+
def Kruskal(self, edges, size):
137+
union_find = UnionFind(size)
138+
139+
edges.sort(key=lambda x: x[2])
140+
141+
ans, cnt = 0, 0
142+
for x, y, dist in edges:
143+
if union_find.is_connected(x, y):
144+
continue
145+
ans += dist
146+
cnt += 1
147+
union_find.union(x, y)
148+
if cnt == size - 1:
149+
return ans
150+
return ans
151+
152+
def minCostConnectPoints(self, points: List[List[int]]) -> int:
153+
size = len(points)
154+
edges = []
155+
for i in range(size):
156+
xi, yi = points[i]
157+
for j in range(i + 1, size):
158+
xj, yj = points[j]
159+
dist = abs(xi - xj) + abs(yi - yj)
160+
edges.append([i, j, dist])
161+
162+
ans = self.Kruskal(edges, size)
163+
return ans
164+
165+
```
166+
167+
### 思路 2:复杂度分析
168+
169+
- **时间复杂度**:$O(m \times \log(n))$。其中 $m$ 为边数,$n$ 为节点数,本题中 $m = n^2$。
170+
- **空间复杂度**:$O(n^2)$。
171+

Templates/08.Graph/Graph-Kruskal.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
class UnionFind:
2+
3+
def __init__(self, n):
4+
self.parent = [i for i in range(n)]
5+
self.count = n
6+
7+
def find(self, x):
8+
while x != self.parent[x]:
9+
self.parent[x] = self.parent[self.parent[x]]
10+
x = self.parent[x]
11+
return x
12+
13+
def union(self, x, y):
14+
root_x = self.find(x)
15+
root_y = self.find(y)
16+
if root_x == root_y:
17+
return
18+
19+
self.parent[root_x] = root_y
20+
self.count -= 1
21+
22+
def is_connected(self, x, y):
23+
return self.find(x) == self.find(y)
24+
25+
26+
class Solution:
27+
def Kruskal(self, edges, size):
28+
union_find = UnionFind(size)
29+
30+
edges.sort(key=lambda x: x[2])
31+
32+
res, cnt = 0, 1
33+
for x, y, dist in edges:
34+
if union_find.is_connected(x, y):
35+
continue
36+
ans += dist
37+
cnt += 1
38+
union_find.union(x, y)
39+
if cnt == size - 1:
40+
return ans
41+
return ans
42+
43+
def minCostConnectPoints(self, points: List[List[int]]) -> int:
44+
size = len(points)
45+
edges = []
46+
for i in range(size):
47+
xi, yi = points[i]
48+
for j in range(i + 1, size):
49+
xj, yj = points[j]
50+
dist = abs(xi - xj) + abs(yi - yj)
51+
edges.append([i, j, dist])
52+
53+
ans = Solution().Kruskal(edges, size)
54+
return ans
55+

Templates/08.Graph/Graph-Prim.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
class Solution:
22
# graph 为图的邻接矩阵,start 为起始顶点
3-
def prim(self, graph, start):
3+
def Prim(self, graph, start):
44
size = len(graph)
55
vis = set()
66
dist = [float('inf') for _ in range(size)]
@@ -44,4 +44,4 @@ def prim(self, graph, start):
4444
graph[j][i] = dist
4545

4646

47-
print(Solution().prim(graph))
47+
print(Solution().Prim(graph))

0 commit comments

Comments
 (0)