题目描述: 给定一个由 1(陆地)和 0(水)组成的矩阵,你需要计算岛屿的数量。岛屿由水平方向或垂直方向上相邻的陆地连接而成,并且四周都是水域。你可以假设矩阵外均被水包围。
输入描述: 第一行包含两个整数 N, M,表示矩阵的行数和列数。 后续 N 行,每行包含 M 个数字,数字为 1 或者 0。
输出描述: 输出一个整数,表示岛屿的数量。如果不存在岛屿,则输出 0。
输入示例:
4 5
1 1 0 0 0
1 1 0 0 0
0 0 1 0 0
0 0 0 1 1
输出示例:3
本题思路: 遇到一个没有遍历过的节点陆地,计数器就加一,然后把该节点陆地所能遍历到的陆地都标记上。 再遇到标记过的陆地节点和海洋节点的时候直接跳过。 这样计数器就是最终岛屿的数量。 那么如果把节点陆地所能遍历到的陆地都标记上呢,就可以使用 DFS,BFS或者并查集。
bfs写法
不少同学用广搜做这道题目的时候,超时了。 这里有一个广搜中很重要的细节:
根本原因是只要 加入队列就代表 走过,就需要标记,而不是从队列拿出来的时候再去标记走过。
from collections import deque
directions = [[0, 1], [1, 0], [0, -1], [-1, 0]]
def bfs(grid, visited, x, y):
que = deque([])
que.append([x,y])
while que:
cur_x, cur_y = que.popleft()
for i, j in directions:
next_x = cur_x + i
next_y = cur_y + j
if next_y < 0 or next_x < 0 or next_x >= len(grid) or next_y >= len(grid[0]):
continue
if not visited[next_x][next_y] and grid[next_x][next_y] == 1:
visited[next_x][next_y] = True
que.append([next_x, next_y])
def main():
n, m = map(int, input().split())
grid = []
for i in range(n):
grid.append(list(map(int, input().split())))
visited = [[False] * m for _ in range(n)]
res = 0
for i in range(n):
for j in range(m):
if grid[i][j] == 1 and not visited[i][j]:
res += 1
bfs(grid, visited, i, j)
print(res)
if __name__ == "__main__":
main()