【Python实战】LeetCode130:被围绕的区域

题目描述

在这里插入图片描述
这道题考察的是图上的搜索问题,通用的策略是深度优先搜索 DFS和广度优先搜索 BFS。题目中解释说被包围的区间不会存在于边界上,所以我们可以考虑对处于边界上或者连通边界的 O 进行特殊处理,那么剩下的 O 就是不在边界上或者不与边界上的 O 相连的 O,将它们替换成 X 就可以了。具体来说,我们可以先对连通边界的 O 替换成其它字符(比如 B),然后遍历整个图把剩下的没被替换的 O 替换成 X,再把所有的 B 变回 O。
在这里插入图片描述
因此,问题转化为:如何寻找和边界联通的 O?

解法一:DFS

从边界出发,对图进行深度优先搜索。只要在边界上找到 O,我们就继续判断它的相邻位置(上下左右)是否还是 O,这样就可以找出所有连通边界的 O了。

class Solution(object):
    def solve(self, board):
        """
        :type board: List[List[str]]
        :rtype: None Do not return anything, modify board in-place instead.
        """
        if not board: return # 如果是空数组,直接返回
        self.rows = len(board) # 行数
        self.cols = len(board[0]) # 列数
        if self.rows < 3 or self.cols < 3: return # 只有3X3及以上的矩阵才有可能出现被包围的‘o’

        # 遍历边界上是否存在‘o’
        for c in range(self.cols): # 遍历第一行和最后一行
            self.dfs(board, 0, c)
            self.dfs(board, self.rows-1, c)
        for r in range(self.rows): # 遍历第一列和最后一列
            self.dfs(board, r, 0)
            self.dfs(board, r, self.cols-1)
        
        # 最后遍历整个二维矩阵,把将所有的‘#’改回‘o’,将所有的‘o’改为‘x’
        for i in range(self.rows):
            for j in range(self.cols):
                if board[i][j] == 'O':
                    board[i][j] = 'X'
                elif board[i][j] == '#':
                    board[i][j] = 'O'

    #---定义dfs递归函数---
    def dfs(self, board, i, j): # 判断第 i行第 j列上是否为‘o’
        # 递归base case
        if i<0 or i>self.rows-1 or j<0 or j> self.cols-1 or board[i][j] != 'O': # 索引超出边界或当前位置不为‘o’,则不继续搜索
            return
        # 否则说明当前位置为‘o’,替换为‘#’
        board[i][j] = '#' 
        # 递归判断当前位置的上下左右是否也为‘o’
        self.dfs(board, i-1, j) # 上
        self.dfs(board, i+1, j) # 下
        self.dfs(board, i, j-1) # 左
        self.dfs(board, i, j+1) # 右

解法二:BFS

广度优先搜索一般借助队列来实现。

class Solution(object):
    def solve(self, board):
        """
        :type board: List[List[str]]
        :rtype: None Do not return anything, modify board in-place instead.
        """
        if not board: return # 如果是空数组,直接返回
        self.rows = len(board) # 行数
        self.cols = len(board[0]) # 列数
        if self.rows < 3 or self.cols < 3: return # 只有3X3及以上的矩阵才有可能出现被包围的‘o’

        # 遍历边界上是否存在‘o’
        for c in range(self.cols): # 遍历第一行和最后一行
            self.bfs(board, 0, c)
            self.bfs(board, self.rows-1, c)
        for r in range(self.rows): # 遍历第一列和最后一列
            self.bfs(board, r, 0)
            self.bfs(board, r, self.cols-1)
        
        # 最后遍历整个二维矩阵,把将所有的‘#’改回‘o’,将所有的‘o’改为‘x’
        for i in range(self.rows):
            for j in range(self.cols):
                if board[i][j] == 'O':
                    board[i][j] = 'X'
                elif board[i][j] == '#':
                    board[i][j] = 'O'

    #---定义bfs函数---
    def bfs(self, board, i, j): # 判断第 i行第 j列上是否为‘o’
        queue = [] # 申请一个空队列
        queue.append((i,j)) # 先把第 i行第 j列的位置入队
        while queue:
            i, j = queue.pop(0) # 弹出队首存储的位置进行判断
            if i<0 or i>self.rows-1 or j<0 or j> self.cols-1 or board[i][j] != 'O' : # 若索引超出边界或当前位置不为‘O’,则不做任何处理,跳过当前循环
                continue
            # 否则,说明当前位置为‘O’,替换为‘#’
            board[i][j] = '#' 
            # 将当前位置的上下左右的位置入队
            queue.append((i-1,j))
            queue.append((i+1,j))
            queue.append((i,j-1))
            queue.append((i,j+1))

最后,如果大家有更好的Python解法,欢迎在评论区分享下您的解法,一起进步,感谢^ o ^~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值