文章目录
- 1. 岛屿问题(岛屿连通)
- 1.1 岛屿数量
- 1.1.1 DFS 解法
- 1.1.2 BFS 解法
深度优先搜索 (DFS) 和广度优先搜索 (BFS)是比较难的算法问题,但也是面试常考题,因此需要认真研究并掌握。
DFS 用递归实现,BFS用栈实现
1. 岛屿问题(岛屿连通)
1.1 岛屿数量
LeetCode链接:LeetCode 200. 岛屿数量
题目:
给你一个由 ‘1’(陆地)和 ‘0’(水)组成的的二维网格,请你计算网格中岛屿的数量。
岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。
此外,你可以假设该网格的四条边均被水包围。
示例 1:
输入:grid = [["1","1","1","1","0"],["1","1","0","1","0"],["1","1","0","0","0"],["0","0","0","0","0"]
]
输出:1
示例 2:
输入:grid = [["1","1","0","0","0"],["1","1","0","0","0"],["0","0","1","0","0"],["0","0","0","1","1"]
]
输出:3
1.1.1 DFS 解法
code:
class Solution:def numIslands(self, grid: List[List[str]]) -> int:# dfs 用递归实现def dfs(i,j):if not 0<=i<len(grid) or not 0<=j<len(grid[0]) or grid[i][j]!="1":return# 遍历完(i,j)后将其标记为水,防止重复搜索grid[i][j]="0"vectors=([i,j+1],[i-1,j],[i,j-1],[i+1,j])for vector in vectors:dfs(vector[0],vector[1])num=0for i in range(len(grid)):for j in range(len(grid[0])):if grid[i][j]=="1":dfs(i,j)num+=1return num
1.1.2 BFS 解法
将 BFS 写成函数的代码写法:
class Solution:def numIslands(self, grid: List[List[str]]) -> int:# 通过bfs将搜索过的节点标记为“0”# bfs通过栈实现(先进先出)def bfs(i,j):if not 0<=i<len(grid) or not 0<=j<len(grid[0]) or grid[i][j]!="1":returnstack.append([i,j])grid[i][j]="0"while stack:stack.pop(0)vectors=([i,j+1],[i-1,j],[i,j-1],[i+1,j])for vector in vectors:bfs(vector[0],vector[1])num=0for i in range(len(grid)):for j in range(len(grid[0])):if grid[i][j]=="1":stack=[]bfs(i,j)num+=1return num
使用迭代而非函数的 BFS 写法:
class Solution:def numIslands(self, grid: List[List[str]]) -> int:num=0for i in range(len(grid)):for j in range(len(grid[0])):if grid[i][j]=="1":# bfs通过栈实现(先进先出)# deque 是双向队列,可以高效的在队列头部和尾部添加、删除元素deque=collections.deque([[i,j]])grid[i][j]="0" # 将搜索过的节点标记为“0”while deque:row,col=deque.popleft()vectors=([row,col+1],[row-1,col],[row,col-1],[row+1,col])for vector in vectors:if 0<=vector[0]<len(grid) and 0<=vector[1]<len(grid[0]) and grid[vector[0]][vector[1]]=="1":deque.append(vector)grid[vector[0]][vector[1]]="0" # 将搜索过的节点标记为“0”num+=1return num
注:
在使用先入先出栈时,应优先使用 collections.deque() 而非 list