数据结构和算法:深度优先搜索 (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

相关推荐
海的诗篇_2 分钟前
移除元素-JavaScript【算法学习day.04】
javascript·学习·算法
自动驾驶小卡13 分钟前
A*算法实现原理以及实现步骤(C++)
算法
Unpredictable22215 分钟前
【VINS-Mono算法深度解析:边缘化策略、初始化与关键技术】
c++·笔记·算法·ubuntu·计算机视觉
编程绿豆侠16 分钟前
力扣HOT100之多维动态规划:1143. 最长公共子序列
算法·leetcode·动态规划
珂朵莉MM22 分钟前
2021 RoboCom 世界机器人开发者大赛-高职组(初赛)解题报告 | 珂学家
java·开发语言·人工智能·算法·职场和发展·机器人
fail_to_code1 小时前
递归法的递归函数何时需要返回值
算法
C137的本贾尼1 小时前
(每日一道算法题)二叉树剪枝
算法·机器学习·剪枝
吴声子夜歌2 小时前
OpenCV——Mat类及常用数据结构
数据结构·opencv·webpack
笑口常开xpr2 小时前
数 据 结 构 进 阶:哨 兵 位 的 头 结 点 如 何 简 化 链 表 操 作
数据结构·链表·哨兵位的头节点
BUG收容所所长3 小时前
栈的奇妙世界:从冰棒到算法的华丽转身
前端·javascript·算法