LeetCode130被围绕的区域

题目描述

给定一个二维的矩阵,包含 'X''O'字母 O)。

找到所有被 'X' 围绕的区域,并将这些区域里所有的 'O''X' 填充。

示例:

1
2
3
4
X X X X
X O O X
X X O X
X O X X

运行你的函数后,矩阵变为:

1
2
3
4
X X X X
X X X X
X X X X
X O X X

解释:

被围绕的区间不会存在于边界上,换句话说,任何边界上的 'O' 都不会被填充为 'X'。 任何不在边界上,或不与边界上的 'O' 相连的 'O' 最终都会被填充为 'X'。如果两个元素在水平或垂直方向相邻,则称它们是“相连”的。

解题思路

第一眼看到这个题目就觉得是对图的搜索遍历,一定是需要使用堆栈或者是队列的。

然后分析本题,首先所有在边界上的 O 是不需要被替换的,我们需要找的是非边界上被包围的 O ,其实也就是把能通过边界上的 O 到达的节点找到即可。

这样稍微转换一下就想明白了,就是按照边界上的 O 进行广度优先搜索就可以。

第一步:

初始化,使用一个队列 Q 来保存边界上的 O,并将其标记出来。

第二步:

队列 Q 取出头部元素,进行广度优先搜索(其实就是上下左右四个方向,判断相应的元素即可)。将搜到的元素进行标记,并将其加入队列中。

第三步:

继续,如果队列 Q 不为空,继续取其头元素,重复执行第二步。

以下是图示:

代码实现

GitHub 代码地址

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
def solve(self, board):
"""
:type board: List[List[str]]
:rtype: void Do not return anything, modify board in-place instead.
"""
if board:

queue = []

for index, i in enumerate(board[0]):
if i == "O":
board[0][index] = "-"
queue.append([0, index])

for index, i in enumerate(board[-1]):
if i == "O":
board[len(board) - 1][index] = "-"
queue.append([len(board) - 1, index])

for i in range(len(board)):
if board[i][0] == "O":
board[i][0] = "-"
queue.append([i, 0])

for i in range(len(board)):
if board[i][-1] == "O":
board[i][len(board[0]) - 1] = "-"
queue.append([i, len(board[0]) - 1])

while queue:
top = queue.pop(0)
x, y = top[0], top[1]
# 上下左右添加
if x - 1 > 0 and board[x - 1][y] == "O":
board[x - 1][y] = "-"
queue.append([x - 1, y])
if x + 1 < len(board) and board[x + 1][y] == "O":
board[x + 1][y] = "-"
queue.append([x + 1, y])
if y - 1 > 0 and board[x][y - 1] == "O":
board[x][y - 1] = "-"
queue.append([x, y - 1])
if y + 1 < len(board[0]) and board[x][y + 1] == "O":
board[x][y + 1] = "-"
queue.append([x, y + 1])

for i in range(len(board)):
for j in range(len(board[0])):
if board[i][j] == "O":
board[i][j] = "X"
if board[i][j] == "-":
board[i][j] = "O"