Leetcode 130:被圍繞的區域(最詳細的解法!!!)
阿新 • • 發佈:2018-12-09
給定一個二維的矩陣,包含 '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
寫成一個迭代版本即可。
如有問題,希望大家指出!!!