广度优先遍历

目录

  • 994.腐烂的橘子
  • 200.岛屿数量
  • 130.被围绕的区域
  • 542.01 矩阵

广度优先搜索(BFS)

  • 思想:从起点开始,逐层向外扩展,先访问所有相邻节点,再访问相邻节点的相邻节点

  • 数据结构:使用队列(先进先出)

  • 应用:最短路径问题、社交网络中的好友关系、网络爬虫等

994.腐烂的橘子

python 复制代码
# 队列实现 BFS 的方法相对固定,大致分三步:
# 初始化队列;
#最开始的坏橘子全部入队,具体是橘子的坐标和 time;
#循环:当队列不为空时,先弹出队首元素,然后将这个元素能够腐烂的橘子全部入队。
class Solution:
    def orangesRotting(self, grid: List[List[int]]) -> int:
        m,n=len(grid),len(grid[0])
        tm=0
        queue =collections.deque()
        directions=[(1,0),(0,1),(-1,0),(0,-1)]  # 4个方向

        for i in range(m):
            for j in range(n):
                if grid[i][j]==2:
                    queue.append((i,j,0)) # 节点位置和该位置节点需要的时间
    
        while queue:
            r,c,tm= queue.popleft()
            for di,dj in directions:
                if 0<=r + di<m and  0<=c+dj <n and grid[r+di][c+dj] ==1:
                    grid[r + di][c + dj] = 2
                    queue.append((r+di,c+dj,tm+1))

    
        for row in grid:
            if 1 in row:
                return -1
        return tm 

200.岛屿数量

python 复制代码
class Solution:
    def numIslands(self, grid: List[List[str]]) -> int:
        # 广度优先搜索,为了求出岛屿的数量,可以扫面整个二维网格。如果一个位置为1,则将其加入队列,开始进行广度优先搜索。
        # 在广度优先搜索的过程中,每个搜索到的1都会被重新标记为0.直到队列为空,搜索结束
        n = len(grid)
        m = len(grid[0])
        res =0
        for i in range(n):
            for j in range(m):
                if grid[i][j] =="1":
                    q= collections.deque()
                    res +=1
                    grid[i][j]=0
                    q.append((i,j))
                    while q:
                        r,c = q.popleft()
                        for x,y in [(r-1,c),(r+1,c),(r,c-1),(r,c+1)]:
                            if 0<=x<n and 0<=y<m and grid[x][y] == "1":
                                q.append((x,y))
                                grid[x][y]="0"
        return res 

130.被围绕的区域

python 复制代码
class Solution:
    def solve(self, board: List[List[str]]) -> None:
        """
        Do not return anything, modify board in-place instead.
        """
        # 任何边界上的0都不会被填充为x,我们可以想到,所有的不被包围的0都直接或者间接与边界上的0相连,我们可以利用这个
        # 性质判断0是否在边界上
        # 第一步:对于每个边界上的0,我们以它为起点,标记所有与它直接或间接相连的0
        # 第二步:遍历这个矩阵,对于每个字母:做操作

        if not board:
            return 
        
        m,n = len(board),len(board[0])
        q= collections.deque()
        for i in range(m):
            if board[i][n-1]=='O':
                q.append((i,n-1))
                board[i][n-1]="1"
            if board[i][0]=='O':
                q.append((i,0))
                board[i][0]="1"
    
        for j in range(n):
            if board[0][j]=='O':
                q.append((0,j))
                board[0][j]="1"
            if board[m-1][j]=='O':
                q.append((m-1,j))
                board[m-1][j]="1"
        while q:
            x,y = q.popleft()
            for r,c in [(x-1,y),(x+1,y),(x,y-1),(x,y+1)]:
                if 0<=r<m and 0<=c<n and board[r][c]=="O":
                    q.append((r,c))
                    board[r][c] ='1'

        for i in range(m):
            for j in range(n):
                if board[i][j]=="1":
                    board[i][j]="O"
                elif board[i][j]=='O':
                    board[i][j]='X'

542.01 矩阵

python 复制代码
class Solution:
    def updateMatrix(self, mat: List[List[int]]) -> List[List[int]]:
        m,n= len(mat),len(mat[0])
        res =[[0]*n for i in range(m)]
        q= collections.deque()
        seen=[]
        for i in range(m):
            for j in range(n):
                if mat[i][j]==0:
                    q.append((i,j)) # 将所有的0添加到初始化队列中
                    seen.append((i,j))

        seen =set(seen)
        while q:   # 广度优先遍历:先遍历每层距离定点超0距离最近的层,逐层遍历,同时已计算的需过滤
            r,c = q.popleft()
            for x,y in [(r+1,c),(r-1,c),(r,c-1),(r,c+1)]:
                if  0<=x<m and 0<=y<n and (x,y) not in seen:  # 不等于0
                    res[x][y] = res[r][c] +1
                    q.append((x,y))
                    seen.add((x,y))
        return res 
相关推荐
业精于勤的牙16 小时前
浅谈:算法中的斐波那契数(二)
算法·职场和发展
不穿格子的程序员17 小时前
从零开始写算法——链表篇4:删除链表的倒数第 N 个结点 + 两两交换链表中的节点
数据结构·算法·链表
liuyao_xianhui17 小时前
寻找峰值--优选算法(二分查找法)
算法
dragoooon3417 小时前
[hot100 NO.19~24]
数据结构·算法
Tony_yitao18 小时前
15.华为OD机考 - 执行任务赚积分
数据结构·算法·华为od·algorithm
C雨后彩虹19 小时前
任务总执行时长
java·数据结构·算法·华为·面试
风筝在晴天搁浅19 小时前
代码随想录 463.岛屿的周长
算法
一个不知名程序员www19 小时前
算法学习入门---priority_queue(C++)
c++·算法
TL滕20 小时前
从0开始学算法——第十八天(分治算法)
笔记·学习·算法