参考文献 代码随想录
一、岛屿数量
题目描述
给定一个由 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
提示信息
根据测试案例中所展示,岛屿数量共有 3 个,所以输出 3。
数据范围:
1 <= N, M <= 50】
深搜
版本1
direction = [[0, 1], [1, 0], [0, -1], [-1, 0]] # 四个方向:上、右、下、左def dfs(grid, visited, x, y):"""对一块陆地进行深度优先遍历并标记"""for i, j in direction:next_x = x + inext_y = y + j# 下标越界,跳过if next_x < 0 or next_x >= len(grid) or next_y < 0 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] = Truedfs(grid, visited, next_x, next_y)if __name__ == '__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 = 0for i in range(n):for j in range(m):# 判断:如果当前节点是陆地,res+1并标记访问该节点,使用深度搜索标记相邻陆地。if grid[i][j] == 1 and not visited[i][j]:res += 1visited[i][j] = Truedfs(grid, visited, i, j)print(res)
版本二
direction = [[0, 1], [1, 0], [0, -1], [-1, 0]] # 四个方向:上、右、下、左def dfs(grid, visited, x, y):"""对一块陆地进行深度优先遍历并标记"""# 与版本一的差别,在调用前增加判断终止条件if visited[x][y] or grid[x][y] == 0:returnvisited[x][y] = Truefor i, j in direction:next_x = x + inext_y = y + j# 下标越界,跳过if next_x < 0 or next_x >= len(grid) or next_y < 0 or next_y >= len(grid[0]):continue# 由于判断条件放在了方法首部,此处直接调用dfs方法dfs(grid, visited, next_x, next_y)if __name__ == '__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 = 0for i in range(n):for j in range(m):# 判断:如果当前节点是陆地,res+1并标记访问该节点,使用深度搜索标记相邻陆地。if grid[i][j] == 1 and not visited[i][j]:res += 1dfs(grid, visited, i, j)print(res)
广搜
n, m = map(int, input().split())
visited = [[False] * m for i in range(n)] # 标记哪些以及走过来,不能重复的计算
grap = []
from collections import deque
for i in range(n):grap.append(list(map(int, input().split())))
def bfs(x, y):que = deque([])que.append([x, y])while que:ix, jy = que.popleft()for next_x, next_y in direction:cur_x = ix + next_xcur_y = jy + next_yif cur_y < 0 or cur_x < 0 or cur_x >= n or cur_y >= m:continueif not visited[cur_x][cur_y] and grap[cur_x][cur_y] == 1:que.append([cur_x, cur_y])visited[cur_x][cur_y] = True
result = 0
direction = [[0, 1], [1, 0], [0, -1], [-1, 0]]
for i in range(n):for j in range(m):if grap[i][j] == 1 and not visited[i][j]: # 为了节省result += 1bfs(i, j) # 一旦发现陆地,将调用函数把它4周链接的给标记,为什么,因为周围的都是一个岛屿
print(result)
二、岛屿的最大面积
题目描述
给定一个由 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
输出示例
4
提示信息
样例输入中,岛屿的最大面积为 4。
数据范围:
1 <= M, N <= 50。
深搜
direction = [[0, 1], [1, 0], [0, -1], [-1, 0]] # 四个方向:右、下、左、上def dfs(grid, visited, x, y):"""对一块陆地进行深度优先遍历,并计算岛屿的面积"""# 初始化当前岛屿的面积area = 1visited[x][y] = True # 标记当前点为已访问for i, j in direction:next_x = x + inext_y = y + j# 下标越界,跳过if next_x < 0 or next_x >= len(grid) or next_y < 0 or next_y >= len(grid[0]):continue# 如果是陆地且没有被访问过,继续 DFSif grid[next_x][next_y] == 1 and not visited[next_x][next_y]:area += dfs(grid, visited, next_x, next_y) # 递归调用 DFS,累加面积return areaif __name__ == '__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)]max_area = 0 # 最大岛屿面积for i in range(n):for j in range(m):# 如果当前节点是陆地且未访问过if grid[i][j] == 1 and not visited[i][j]:# 计算岛屿面积max_area = max(max_area, dfs(grid, visited, i, j))print(max_area)
广搜
direction = [[0, 1], [1, 0], [0, -1], [-1, 0]] # 四个方向:右、下、左、上
from collections import deque
def dfs(grid, visited, x, y):"""对一块陆地进行深度优先遍历,并计算岛屿的面积"""# 初始化当前岛屿的面积que = deque([])que.append([x, y])area = 1visited[x][y] = True # 标记当前点为已访问while que:xx, yy = que.popleft()for i, j in direction:next_x = xx + inext_y = yy + j# 下标越界,跳过if next_x < 0 or next_x >= len(grid) or next_y < 0 or next_y >= len(grid[0]):continue# 如果是陆地且没有被访问过,继续 DFSif grid[next_x][next_y] == 1 and not visited[next_x][next_y]:visited[next_x][next_y] = Trueque.append([next_x,next_y])area += 1return areaif __name__ == '__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)]max_area = 0 # 最大岛屿面积for i in range(n):for j in range(m):# 如果当前节点是陆地且未访问过if grid[i][j] == 1 and not visited[i][j]:# 计算岛屿面积max_area = max(max_area, dfs(grid, visited, i, j))print(max_area)