图解LeetCode——200. 岛屿数量
2023-09-12 01:15:43
如何征服 LeetCode 第 200 题:“岛屿数量”
准备好潜入算法问题的海洋了吗?让我们共同征服 LeetCode 第 200 题:“岛屿数量”。在这篇文章中,我们将探索三种解决此问题的强大算法:深度优先搜索、广度优先搜索和并查集算法。
1. 深度优先搜索:深入探险
想象一下自己像一位探险家,深入探索一个迷宫。深度优先搜索(DFS)就是这样的算法,它沿着一条路径一直探索下去,直到遇到死路,然后再回溯寻找其他路径。在我们的“岛屿数量”问题中,DFS 会从网格的一角开始,标记陆地并继续搜索相邻的陆地。当它完成探索后,就会返回岛屿数量。
优点:
- 易于理解和实现
- 内存消耗较小
缺点:
- 可能出现栈溢出问题
2. 广度优先搜索:逐层拓展
广度优先搜索(BFS)就像一个拓荒者,它一层一层地探索网格,从未被访问过的陆地开始。BFS 会将陆地添加到一个队列中,并一层一层地探索它们。通过这种方法,它可以避免栈溢出问题。
优点:
- 避免栈溢出问题
- 适用于大网格
缺点:
- 可能会探索一些不必要的区域
3. 并查集算法:高效管理
并查集算法是一个强大的数据结构,它可以管理元素集合。在我们的问题中,我们将每个陆地视为一个集合。并查集算法会将相邻的陆地合并到同一个集合中,最后返回集合数量,即岛屿数量。
优点:
- 高效处理大量数据
- 无需遍历整个网格
缺点:
- 实现复杂度高
代码示例:
Python (DFS):
def num_islands(grid):
def dfs(i, j):
if i < 0 or i >= len(grid) or j < 0 or j >= len(grid[0]) or grid[i][j] == '0':
return
grid[i][j] = '0' # 标记已访问
dfs(i + 1, j)
dfs(i - 1, j)
dfs(i, j + 1)
dfs(i, j - 1)
count = 0
for i in range(len(grid)):
for j in range(len(grid[0])):
if grid[i][j] == '1':
count += 1
dfs(i, j)
return count
Python (BFS):
from collections import deque
def num_islands(grid):
def bfs(i, j):
queue = deque([(i, j)])
while queue:
x, y = queue.popleft()
if x < 0 or x >= len(grid) or y < 0 or y >= len(grid[0]) or grid[x][y] == '0':
continue
grid[x][y] = '0' # 标记已访问
queue.append((x + 1, y))
queue.append((x - 1, y))
queue.append((x, y + 1))
queue.append((x, y - 1))
count = 0
for i in range(len(grid)):
for j in range(len(grid[0])):
if grid[i][j] == '1':
count += 1
bfs(i, j)
return count
Python (并查集):
class UnionFind:
def __init__(self):
self.parent = {}
def find(self, x):
if x not in self.parent:
self.parent[x] = x
elif self.parent[x] != x:
self.parent[x] = self.find(self.parent[x])
return self.parent[x]
def union(self, x, y):
root_x = self.find(x)
root_y = self.find(y)
if root_x != root_y:
self.parent[root_x] = root_y
def num_islands(grid):
uf = UnionFind()
for i in range(len(grid)):
for j in range(len(grid[0])):
if grid[i][j] == '1':
if i > 0 and grid[i - 1][j] == '1':
uf.union((i, j), (i - 1, j))
if j > 0 and grid[i][j - 1] == '1':
uf.union((i, j), (i, j - 1))
count = 0
for i in range(len(grid)):
for j in range(len(grid[0])):
if grid[i][j] == '1' and uf.find((i, j)) == (i, j):
count += 1
return count
常见问题解答
1. 哪种算法最适合解决“岛屿数量”问题?
这取决于网格的大小和特定情况。对于小网格,DFS 和 BFS 都可以很好地工作。对于大网格,并查集算法更有效。
2. DFS 和 BFS 有什么区别?
DFS 深入探索一条路径,而 BFS 逐层拓展。DFS 可能遇到栈溢出问题,而 BFS 可以避免这个问题。
3. 并查集算法如何工作?
并查集算法使用两个操作:合并和查找。合并将集合合并在一起,查找返回一个元素所属的集合。
4. 为什么并查集算法比 DFS 和 BFS 更高效?
并查集算法无需遍历整个网格,因为它使用并查集数据结构高效地管理集合。
5. “岛屿数量”问题还有其他解决方法吗?
是的,还有其他解决方法,如循环检测或图像处理技术。