Skip to content

Commit 1017539

Browse files
committed
Update 01.Queue-BFS.md
1 parent 7e30deb commit 1017539

File tree

1 file changed

+116
-8
lines changed

1 file changed

+116
-8
lines changed

Contents/04.Queue/02.Queue-BFS/01.Queue-BFS.md

Lines changed: 116 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,12 @@ graph = {
2626

2727
该无向图的结构如图左所示,图右为宽度优先搜索的遍历路径。
2828

29+
![](https://qcdn.itcharge.cn/images/20220105135253.png)
30+
2931
其对应的动态演示图如下所示。
3032

33+
![](https://qcdn.itcharge.cn/images/20220105135158.gif)
34+
3135
## 3. 基于队列实现的广度优先搜索
3236

3337
### 3.1 基于队列实现的广度优先搜索实现步骤
@@ -43,27 +47,91 @@ graph = {
4347
### 3.2 基于队列实现的广度优先搜索实现代码
4448

4549
```Python
46-
from queue import Queue
50+
import collections
4751

4852
def bfs(graph, start):
4953
visited = set(start)
50-
q = Queue()
51-
q.put(start)
52-
while not q.empty():
53-
node_u = q.get()
54+
q = collections.deque([start])
55+
56+
while q:
57+
node_u = q.popleft()
5458
print(node_u)
5559
for node_v in graph[node_u]:
5660
if node_v not in visited:
5761
visited.add(node_v)
58-
q.put(node_v)
62+
q.append(node_v)
5963
```
6064

6165
## 4. 广度优先搜索应用
6266

63-
### 4.1 岛屿的最大面积
67+
### 4.1 无向图中连通分量的数目
6468

6569
#### 4.1.1 题目链接
6670

71+
- [323. 无向图中连通分量的数目 - 力扣(LeetCode)](https://leetcode-cn.com/problems/number-of-connected-components-in-an-undirected-graph/)
72+
73+
#### 4.1.2 题目大意
74+
75+
给定 `n` 个节点(编号从 `0``n - 1`)的图的无向边列表 `edges`,其中 `edges[i] = [u, v]` 表示节点 `u` 和节点 `v` 之间有一条无向边。
76+
77+
要求:计算该无向图中连通分量的数量。
78+
79+
#### 4.1.3 解题思路
80+
81+
先来看一下图论中相关的名次解释。
82+
83+
- 连通图:在无向图中,如果可以从顶点 $v_i$ 到达 $v_j$,则称 $v_i$ 和 $v_j$ 连通。如果图中任意两个顶点之间都连通,则称该图为连通图。
84+
- 无向图的连通分量:如果该图为连通图,则连通分量为本身;否则将无向图中的极大连通子图称为连通分量,每个连通分量都是一个连通图。
85+
- 无向图的连通分量个数:无向图的极大连通子图的个数。
86+
87+
接下来我们来解决这道题。
88+
89+
由于题目给定的是无向边列表。我们先将其转变为邻接表的形式。然后使用广度优先搜索计算联通分量的个数。具体做法如下:
90+
91+
- 使用变量 `count` 记录连通分量个数。使用集合变量 `visited` 记录访问过的节点,使用邻接表 `graph` 记录图结构。
92+
-`0` 开始,依次遍历 `n` 个节点。
93+
- 如果第 `i` 个节点未访问过:
94+
- 将其添加到 `visited` 中。
95+
- 并且连通分量个数累加,即 `count += 1`
96+
- 定义一个队列 `q`,将第 `i` 个节点加入到队列中。
97+
- 从队列中取出第一个节点,遍历与其链接的节点,并将未遍历过的节点加入到队列 `q``visited` 中。
98+
- 直到队列为空,则继续向后遍历。
99+
100+
- 最后输出连通分量数目 `count`
101+
102+
#### 4.1.4 代码
103+
104+
```Python
105+
import collections
106+
107+
class Solution:
108+
def countComponents(self, n: int, edges: List[List[int]]) -> int:
109+
count = 0
110+
visited = set()
111+
graph = [[] for _ in range(n)]
112+
113+
for x, y in edges:
114+
graph[x].append(y)
115+
graph[y].append(x)
116+
117+
for i in range(n):
118+
if i not in visited:
119+
visited.add(i)
120+
count += 1
121+
q = collections.deque([i])
122+
while q:
123+
node_u = q.popleft()
124+
for node_v in graph[node_u]:
125+
if node_v not in visited:
126+
visited.add(node_v)
127+
q.append(node_v)
128+
return count
129+
```
130+
131+
### 4.2 岛屿的最大面积
132+
133+
#### 4.2.1 题目链接
134+
67135
- [695. 岛屿的最大面积 - 力扣(LeetCode)](https://leetcode-cn.com/problems/max-area-of-island/)
68136

69137
#### 4.2.2 题目大意
@@ -72,12 +140,52 @@ def bfs(graph, start):
72140

73141
要求:计算出最大的岛屿面积。
74142

143+
示例 :
144+
145+
![img](https://assets.leetcode.com/uploads/2021/05/01/maxarea1-grid.jpg)
146+
147+
图中最大的岛屿面积为 6。
148+
75149
#### 4.2.3 解题思路
76150

151+
使用广度优先搜索方法。具体做法如下:
152+
153+
1. 使用 `ans` 记录最大岛屿面积。
154+
2. 遍历二维数组的每一个元素,对于每个值为 `1` 的元素:
155+
1. 将该元素置为 `0`。并使用队列 `q` 存储该节点位置。使用 `temp_ans` 记录当前岛屿面积。
156+
2. 然后从队列 `q` 中取出第一个节点位置 `(i, j)`。遍历该节点位置上、下、左、右四个方向上的相邻节点。并将其置为 `0`(避免重复搜索)。并将其加入到队列中。并累加当前岛屿面积,即 `temp_ans += 1`
157+
3. 不断重复上一步骤,直到队列 `q` 为空。
158+
4. 更新当前最大岛屿面积,即 `ans = max(ans, temp_ans)`
159+
77160
#### 4.2.4 代码
78161

79162
```Python
80-
163+
import collections
164+
165+
class Solution:
166+
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
167+
directs = [(0, 1), (0, -1), (1, 0), (-1, 0)]
168+
rows, cols = len(grid), len(grid[0])
169+
ans = 0
170+
for i in range(rows):
171+
for j in range(cols):
172+
if grid[i][j] == 1:
173+
grid[i][j] = 0
174+
temp_ans = 1
175+
q = collections.deque([(i, j)])
176+
while q:
177+
i, j = q.popleft()
178+
for direct in directs:
179+
new_i = i + direct[0]
180+
new_j = j + direct[1]
181+
if new_i < 0 or new_i >= rows or new_j < 0 or new_j >= cols or grid[new_i][new_j] == 0:
182+
continue
183+
grid[new_i][new_j] = 0
184+
q.append((new_i, new_j))
185+
temp_ans += 1
186+
187+
ans = max(ans, temp_ans)
188+
return ans
81189
```
82190

83191
## 参考资料

0 commit comments

Comments
 (0)