算法设计与分析:Surrounded Regions(Week 3)

学号:16340008


Question:

Given a 2D board containing 'X' and 'O' (the letter O), capture all regions surrounded by 'X'.

A region is captured by flipping all 'O's into 'X's in that surrounded region.

Example:

X X X X
X O O X
X X O X
X O X X

After running your function, the board should be:

X X X X
X X X X
X X X X
X O X X

Explanation:

Surrounded regions shouldn’t be on the border, which means that any 'O' on the border of the board are not flipped to 'X'. Any 'O' that is not on the border and it is not connected to an 'O' on the border will be flipped to 'X'. Two cells are connected if they are adjacent cells connected horizontally or vertically.


Answer:

考虑到这周学习图,便挑了一道DFS的题目做。题意相当于对被X包围(不包括边界)的O或O块,替换为X,有点类似围棋的吃。换而言之,所有不接触边界的O或O块,都将被替换。因此,需要选取O,并对他的四周进行判断,假如四周某方向为O,就向下搜索。万一其中某个O四周接触到边界,则这个根O的所有子O都将安全。

我的算法主要如下:

  1. 对矩阵中的每个字母作第2步操作。
  2. 当字母为O时,重复3到6步。
  3. 将这个O改为X,其坐标加入集合post内,并对这个O的四周判断
  4. 若四周中某个方向同样为O且不出矩阵,则对这个O重复第3到6步
  5. 若这个O在边界,则函数中的布尔变量改为True
  6. 对函数每次递归的所有返回进行“或”运算,若结果为True,说明O块接触边界,将post中的元素放入keep记录并清空post,若结果为False,说明O块不接触边界,直接清空post即可。
  7. 对容器keep中每个坐标内的X改为O。

算法对每个X判断一次,对每个应转换的O判断一次并转换一次,对每个不应转换的O判断一次,转换两次。最终Runtime为188ms。(语言:Python3)

class Solution:
    post = []
    keep = []
    def solve(self, board):
        """
        :type board: List[List[str]]
        :rtype: void Do not return anything, modify board in-place instead.
        """
        for i in range(len(board)):
            for j in range(len(board[i])):
                if "O" == board[i][j]:
                    if self.DFS(i, j, board):
                        self.keep = self.keep + self.post
                    self.post.clear()
        for [i,j] in self.keep:
            board[i][j] = "O"

    def DFS(self, i, j, board):
        self.post.append([i,j])
        board[i][j] = "X"
        
        flag = False
        if i > 0 and "O" == board[i-1][j]:
            temp = self.DFS(i-1, j, board)
            flag = temp or flag
        if i < len(board)-1 and "O" == board[i+1][j]:
            temp = self.DFS(i+1, j, board)
            flag = temp or flag
        if j > 0 and "O" == board[i][j-1]:
            temp = self.DFS(i, j-1, board)
            flag = temp or flag
        if j < len(board[i])-1 and "O" == board[i][j+1]:
            temp = self.DFS(i, j+1, board)
            flag = temp or flag
        if i == 0 or i == len(board)-1 or j == 0 or j == len(board[i]) - 1:
            flag = True
        return flag

'''
test = Solution()
board = [["O","O","O","O","X","X"],["O","O","O","O","O","O"],["O","X","O","X","O","O"],["O","X","O","O","X","O"],["O","X","O","X","O","O"],["O","X","O","O","O","O"]]
test.solve(board)
print(board)
'''

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值