深度优先搜索
总结记录DFS算法相关内容
1. 说明
1.1 概念
深度优先搜索(Depth First Search,DFS)属于图算法的一种:对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次。
1.2 算法实现
DFS中最重要的算法思想是回溯和剪枝。基于此,要实现DFS搜索,常依托于**堆栈(递归)**的方式。
回溯法
- 回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标。
- 当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。
剪枝
减小搜索树规模、排除搜索树中不必要的分支的一种手段。形象地看,就好像剪掉了搜索树的枝条,故称之为“剪枝”。
1.3 基础模板
def dfs(step):
"""
:param step: 状态
"""
if step == '边界状态':
return '结果'
for way in '所有可能':
if way in '检查条件':
step += '添加标记'
dfs(step)
step -= '删除标记(回溯)'
2. 实例
class Solution:
def floodFill(self, image: list, sr: int, sc: int, color: int) -> list:
from queue import Queue, LifoQueue
if color == image[sr][sc]:
# 如果起始点与待染色色号相同,直接返回
return image
rows, cols = len(image), len(image[0])
directions = {(0, 1), (0, -1), (1, 0), (-1, 0)}
# dfs :遍历附件相连同色块,并染色
stack, original_color = LifoQueue(), image[sr][sc]
stack.put((sr, sc))
while not stack.empty():
row, col = stack.get()
image[row][col] = color
for r, c in directions:
new_r = row + r
new_c = col + c
if 0 <= new_r < rows and 0 <= new_c < cols and image[new_r][new_c] == original_color:
stack.put((new_r, new_c))
return image
def numIslands(grid: list) -> int:
from queue import Queue, LifoQueue
directions = {(0, 1), (0, -1), (1, 0), (-1, 0)}
res = 0
dfs
rows, cols = len(grid), len(grid[0])
checks = [[0 for _ in range(cols)] for _ in range(rows)]
for r in range(rows):
for c in range(cols):
if grid[r][c] == "0" or checks[r][c] != 0:
# 跳过不为岛屿,或已经遍历过的点
checks[r][c] = 1
continue
checks[r][c] = 1 # 标记当前点已经遍历
res += 1 # 岛屿计数加一
# 通过DFS方法,遍历标记与当前位置相连接的陆地
stack = LifoQueue()
stack.put((r, c))
while not stack.empty():
row, col = stack.get()
for dr, dc in directions:
new_r, new_c = row + dr, col + dc
if 0 <= new_r < rows and 0 <= new_c < cols and \
grid[new_r][new_c] == "1" and checks[new_r][new_c] == 0:
checks[new_r][new_c] = 1
stack.put((new_r, new_c))
return res
def maxAreaOfIsland(grid: list) -> int:
from queue import Queue, LifoQueue
res = 0
directions = {(0, 1), (0, -1), (1, 0), (-1, 0)}
rows, cols = len(grid), len(grid[0])
island = [[0 for _ in range(cols)] for _ in range(rows)]
for r in range(rows):
for c in range(cols):
if grid[r][c] != 1 or island[r][c] == 1:
island[r][c] = 1
continue
tmp = 1
island[r][c] = 1
stack = LifoQueue() # 创建栈(后进先出),一直向同一方向检索再回溯,实现dfs
stack.put((r, c))
while not stack.empty():
row, col = stack.get()
for dr, dc in directions:
nr, nc = dr + row, dc + col
if 0 <= nr < rows and 0 <= nc < cols and grid[nr][nc] == 1 and \
island[nr][nc] == 0:
tmp += 1
island[nr][nc] = 1
stack.put((nr, nc))
res = max(res, tmp)
return res
参考文档
[1]深度优先搜索(百度百科)