(待更..)【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'。如果两个元素在水平或垂直方向相邻,则称它们是“相连”的。
解答
典型的搜索题,深度优先和广度优先都可以。(并查集也可以解决,待更..)
1,深度优先dfs,用递归。Time: O(mn),Space:O(mn)。先把边缘的或与边缘相邻的'O'
替换为'.'
,剩下的'O'
就是目标。
2,广度优先bfs,用队列。Time: O(mn),Space:O(mn)。'O'
替换为'.'
过程用广搜即可。
# 深搜
class Solution:
def __init__(self):
self.a = []
self.next = [
[0, 1],
[1, 0],
[0, -1],
[-1, 0]
]
self.m = 0
self.n = 0
def solve(self, board) -> None:
if not board:
return []
self.a = board
self.m, self.n = len(board), len(board[0])
# 1, 将和边界相连的'O'字符替换成'.'
for i in range(self.m):
for j in range(self.n):
if self.a[i][j] == 'O' and (j==0 or j==self.n-1 or i==0 or i==self.m-1):
self.a[i][j] = '.'
self.dfs(i, j)
import pprint
pprint.pprint(self.a)
# 2, 剩下的'O'就是目标,替换成'X'; 将'.'还原成'O'
for i in range(self.m):
for j in range(self.n):
if self.a[i][j] == 'O':
self.a[i][j] = 'X'
elif self.a[i][j] == '.':
self.a[i][j] = 'O'
import pprint
pprint.pprint(self.a)
def dfs(self, x, y):
for i in range(4):
tx = x + self.next[i][0]
ty = y + self.next[i][1]
if tx >= 0 and ty >= 0 and tx < self.m and ty < self.n and self.a[tx][ty] == 'O':
self.a[tx][ty] = '.'
self.dfs(tx, ty)
s = Solution()
s.solve([['X', 'X', 'X', 'X'],
['X', 'O', 'X', 'X'],
['X', 'X', 'O', 'X'],
['X', 'O', 'O', 'X']])
# [['X', 'X', 'X', 'X'],
# ['X', 'O', 'X', 'X'],
# ['X', 'X', '.', 'X'],
# ['X', '.', '.', 'X']]
#
# [['X', 'X', 'X', 'X'],
# ['X', 'X', 'X', 'X'],
# ['X', 'X', 'O', 'X'],
# ['X', 'O', 'O', 'X']]