给你一个 m x n 的矩阵 board ,由若干字符 ‘X’ 和 ‘O’ ,找到所有被 ‘X’ 围绕的区域,并将这些区域里所有的 ‘O’ 用 ‘X’ 填充。
示例 1:
输入:board = [[“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’。如果两个元素在水平或垂直方向相邻,则称它们是“相连”的。
示例 2:
输入:board = [[“X”]]
输出:[[“X”]]
根据题目可知,边界以及和边界相连的O不用变成X,其他的O都变成X。根据这个信息,解题思路如下:
- 遍历board的边界,找到所有边界值为O的位置,并将位置记录在集合h1中
- 对h1中的边界点进行深度优先搜索,每一次dfs搜索出和一个边界O所有相连的O点坐标,并保存在集合h2中
- 合并h1和h2为h3,h3中记录的是不需要变为X的O,其他的O都要变为X
- 在原列表上,遍历原列表,将不在h3中的O改为X
代码如下:
class Solution:
def solve(self, board):
h1=set() #记录最外层一圈没有被包围的O
h2=set() #记录与最外层相连的O
########################### 找到最外层的O
for i in range(len(board)):
if board[i][0]=="O":
h1.add((i,0))
if board[i][-1]=="O":
h1.add((i,len(board[0])-1))
for i in range(len(board[0])):
if board[0][i]=="O":
h1.add((0,i))
if board[-1][i]=="O":
h1.add((len(board)-1,i))
###########################
# 找到所有和边界相连的O的位置并将它们添进h2集合中
def dfs(place,h2,board):
i=place[0]
j=place[1]
for (dx,dy) in [(i,j-1),(i,j+1),(i-1,j),(i+1,j)]:
if dx>0 and dy>0 and dx<len(board) and dy<len(board[0]) and board[dx][dy]=="O" and (dx,dy) not in h2:
h2.add((dx,dy))
dfs((dx,dy),h2,board)
for i in h1:
dfs(i,h2,board)
###########################
h3=h1|h2 #合并两个集合,h3集合中包含了所有不需要改为X的集合
###########################
#改变原列表
for i in range(len(board)):
for j in range(len(board[0])):
if board[i][j]=="O" and (i,j) not in h3:
board[i][j]="X"
#return board