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

深度优先搜索 (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 解法

code:

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

注:

在使用先入先出栈时,应优先使用 collections.deque() 而非 list

猜你喜欢

转载自blog.csdn.net/qq_43799400/article/details/131782950