Структуры данных и алгоритмы: поиск в глубину (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

код:

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

Примечание:

При использовании стека first-in-first-out следует использовать collections.deque() вместо перечисления

Guess you like

Origin blog.csdn.net/qq_43799400/article/details/131782950
Recommended