数据结构和算法:深度优先搜索 (DFS) 和广度优先搜索 (BFS) 相关题目

文章目录

    • [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

相关推荐
承渊政道1 小时前
【动态规划算法】(完全背包问题从状态定义到空间优化)
数据结构·c++·学习·算法·leetcode·动态规划·哈希算法
超级大福宝1 小时前
【力扣48. 旋转图像】超好记忆版 + 口诀
c++·算法·leetcode
爱写代码的倒霉蛋1 小时前
2023年天梯赛L1-8
数据结构·算法
apollowing1 小时前
启发式算法WebApp实验室:从搜索策略到群体智能的能力进阶(上)
算法·启发式算法·web app
生物信息与育种2 小时前
黄三文院士领衔植物星球计划(PLANeT)发表Cell
人工智能·深度学习·算法·面试·transformer
aini_lovee2 小时前
WSN 四大经典无需测距定位算法
算法
人道领域2 小时前
【LeetCode刷题日记】掌握二叉树遍历:栈实现的三种绝妙方法
算法·leetcode·职场和发展
北冥湖畔的燕雀2 小时前
深入解析Linux信号处理机制
算法
阿Y加油吧2 小时前
二刷 LeetCode:动态规划经典双题复盘
算法·leetcode·动态规划
上弦月-编程2 小时前
C语言指针超详细教程——从入门到精通(面向初学者)
java·数据结构·算法