文章目录
-
- [1. 岛屿问题(岛屿连通)](#1. 岛屿问题(岛屿连通))
-
- [1.1 岛屿数量](#1.1 岛屿数量)
-
- [1.1.1 DFS 解法](#1.1.1 DFS 解法)
- [1.1.2 BFS 解法](#1.1.2 BFS 解法)
深度优先搜索 (DFS) 和广度优先搜索 (BFS)是比较难的算法问题,但也是面试常考题,因此需要认真研究并掌握。
DFS 用递归实现,BFS用栈实现
1. 岛屿问题(岛屿连通)
1.1 岛屿数量
LeetCode链接:LeetCode 200. 岛屿数量
题目:
给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。
岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。
此外,你可以假设该网格的四条边均被水包围。
示例 1:
bash
输入:grid = [
["1","1","1","1","0"],
["1","1","0","1","0"],
["1","1","0","0","0"],
["0","0","0","0","0"]
]
输出:1
示例 2:
bash
输入: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:
python
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=0
for i in range(len(grid)):
for j in range(len(grid[0])):
if grid[i][j]=="1":
dfs(i,j)
num+=1
return num
1.1.2 BFS 解法
将 BFS 写成函数的代码写法:
python
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":
return
stack.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=0
for i in range(len(grid)):
for j in range(len(grid[0])):
if grid[i][j]=="1":
stack=[]
bfs(i,j)
num+=1
return num
使用迭代而非函数的 BFS 写法:
python
class Solution:
def numIslands(self, grid: List[List[str]]) -> int:
num=0
for 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+=1
return num
注:
在使用先入先出栈时,应优先使用 collections.deque() 而非 list