leetcode---130.被围绕的区域(深度优先搜索dfs)

给你一个 m x n 的矩阵 board ,由若干字符 ‘X’ 和 ‘O’ ,找到所有被 ‘X’ 围绕的区域,并将这些区域里所有的 ‘O’ 用 ‘X’ 填充。

示例 1:
输入:board = [[“X”,“X”,“X”,“X”],[“X”,“O”,“O”,“X”],[“X”,“X”,“O”,“X”],[“X”,“O”,“X”,“X”]]
输出:[[“X”,“X”,“X”,“X”],[“X”,“X”,“X”,“X”],[“X”,“X”,“X”,“X”],[“X”,“O”,“X”,“X”]]
解释:被围绕的区间不会存在于边界上,换句话说,任何边界上的 ‘O’ 都不会被填充为 ‘X’。 任何不在边界上,或不与边界上的 ‘O’ 相连的 ‘O’ 最终都会被填充为 ‘X’。如果两个元素在水平或垂直方向相邻,则称它们是“相连”的。
示例 2:

输入:board = [[“X”]]
输出:[[“X”]]

根据题目可知,边界以及和边界相连的O不用变成X,其他的O都变成X。根据这个信息,解题思路如下:

  1. 遍历board的边界,找到所有边界值为O的位置,并将位置记录在集合h1中
  2. 对h1中的边界点进行深度优先搜索,每一次dfs搜索出和一个边界O所有相连的O点坐标,并保存在集合h2中
  3. 合并h1和h2为h3,h3中记录的是不需要变为X的O,其他的O都要变为X
  4. 在原列表上,遍历原列表,将不在h3中的O改为X

代码如下:

class Solution:
    def solve(self, board):
        h1=set()     #记录最外层一圈没有被包围的O
        h2=set()     #记录与最外层相连的O
        ########################### 找到最外层的O
        for i in range(len(board)):
            if board[i][0]=="O":
                h1.add((i,0))
            if board[i][-1]=="O":
                h1.add((i,len(board[0])-1))
        for i in range(len(board[0])):
            if board[0][i]=="O":
                h1.add((0,i))
            if board[-1][i]=="O":
                h1.add((len(board)-1,i))
        ###########################
        # 找到所有和边界相连的O的位置并将它们添进h2集合中
        def dfs(place,h2,board):
            i=place[0]
            j=place[1]
            for (dx,dy) in [(i,j-1),(i,j+1),(i-1,j),(i+1,j)]:
                if dx>0 and dy>0 and dx<len(board) and dy<len(board[0]) and board[dx][dy]=="O" and (dx,dy) not in h2:
                    h2.add((dx,dy))
                    dfs((dx,dy),h2,board)
        for i in h1:
            dfs(i,h2,board)
        ###########################
        h3=h1|h2    #合并两个集合,h3集合中包含了所有不需要改为X的集合
        ###########################
        #改变原列表
        for i in range(len(board)):
            for j in range(len(board[0])):
                if board[i][j]=="O" and (i,j) not in h3:
                    board[i][j]="X"
        #return board
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

happylife_mini

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值