Каталог статей
Поиск в глубину (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
код:
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 как функции:
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 с использованием итераций вместо функций:
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
Примечание:
При использовании стека first-in-first-out следует использовать collections.deque() вместо перечисления