深度优先搜索DFS

深度优先搜索

总结记录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. 实例

leetcode733. 图像渲染

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

leetcode200. 岛屿数量

    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

leetcode695. 岛屿的最大面积

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]深度优先搜索(百度百科)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值