1. 程式人生 > >Leetcode 130:被圍繞的區域(最詳細的解法!!!)

Leetcode 130:被圍繞的區域(最詳細的解法!!!)

給定一個二維的矩陣,包含 'X''O'字母 O)。

找到所有被 'X' 圍繞的區域,並將這些區域裡所有的 'O''X' 填充。

示例:

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'。如果兩個元素在水平或垂直方向相鄰,則稱它們是“相連”的。

解題思路

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

這裡的O全部就外圍元素。所以我們現在的問題就變成了,在這個圖的邊界位置出發找連通的O,這就和之前的問提聯絡在一起了。

class Solution:
    def solve(self, board):
        """
        :type board: List[List[str]]
        :rtype: void Do not return anything, modify board in-place instead.
        """
        if not board:
            return
None m, n = len(board), len(board[0]) d = [(-1, 0), (0, 1), (1, 0), (0, -1)] def _solve(i, j): if 0 <= i < m and 0 <= j < n and board[i][j] == 'O': board[i][j] = '*' for k in range(4): _solve(i + d[k][0], j + d[k][1
]) for i in range(m): _solve(i, 0) _solve(i, n - 1) for i in range(n): _solve(0, i) _solve(m - 1, i) for i in range(m): for j in range(n): if board[i][j] == 'O': board[i][j] = 'X' elif board[i][j] == '*': board[i][j] = 'O'

我們有一個更pythonic的寫法。

class Solution:
    def solve(self, board):
        """
        :type board: List[List[str]]
        :rtype: void Do not return anything, modify board in-place instead.
        """
        if not board:
            return None

        m, n = len(board), len(board[0])

        def _solve(i, j):
            if 0 <= i < m and 0 <= j < n and board[i][j] == 'O':
                board[i][j] = '*'
                list(map(_solve, (i+1, i-1, i, i), (j, j, j+1, j-1)))

        for i in range(m):
            list(map(_solve, (i, i), (0, n - 1)))

        for i in range(n):
            list(map(_solve, (0, m - 1), (i, i)))

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

要注意的是python3中,map函式返回的是一個iterator,所以我們要通過list將包在外面,去自動推導它。

同樣的,對於遞迴解決的問題,我們都應該思考一下怎麼通過迭代去解決。寫法和Leetcode 200:島嶼的個數(最詳細的解法!!!)問題中的迭代版本寫法類似。

class Solution:
    def solve(self, board):
        """
        :type board: List[List[str]]
        :rtype: void Do not return anything, modify board in-place instead.
        """
        if not board:
            return None

        m, n = len(board), len(board[0])

        def _solve(i, j):
            if board[i][j] != 'O':
                return

            stack = list()
            stack.append((i, j))
            while stack:
                x, y  = stack.pop()
                if board[x][y] != 'O':
                    continue

                board[x][y] = '*'
                directions = [(-1, 0), (0, 1), (1, 0), (0, -1)]
                for d in directions:
                    nr = x + d[0]
                    nc = y + d[1]
                    if 0 <= nr < m and 0 <= nc < n:
                        stack.append((nr, nc))

        for i in range(m):
            list(map(_solve, (i, i), (0, n - 1)))

        for i in range(n):
            list(map(_solve, (0, m - 1), (i, i)))

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

我們將self._solve寫成一個迭代版本即可。

如有問題,希望大家指出!!!