Given an m x n
matrix board
containing 'X'
and 'O'
, capture all regions that are 4-directionally surrounded by 'X'
.
A region is captured by flipping all 'O'
s into 'X'
s in that surrounded region.
Example 1:
Input: board = [["X","X","X","X"],["X","O","O","X"],["X","X","O","X"],["X","O","X","X"]] Output: [["X","X","X","X"],["X","X","X","X"],["X","X","X","X"],["X","O","X","X"]] Explanation: Surrounded regions should not be on the border, which means that any 'O' on the border of the board are not flipped to 'X'. Any 'O' that is not on the border and it is not connected to an 'O' on the border will be flipped to 'X'. Two cells are connected if they are adjacent cells connected horizontally or vertically.
Example 2:
Input: board = [["X"]] Output: [["X"]]
Constraints:
m == board.length
n == board[i].length
1 <= m, n <= 200
board[i][j]
is'X'
or'O'
.
跟求封闭岛屿题 Leetcode1254. Number of Closed Islands 基本上一样。先用并查集(Union Find)合并所有相连的‘O’的集合,同时标注‘O’集合是否为封闭的。最后遍历一遍矩阵把属于封闭集合的‘O’改成‘X’。具体分析可以参考 Leetcode1254. Number of Closed Islands
class UnionFind :
def __init__(self, n) :
self.parent = [-1] * n
self.size = [0] * n
self.isClosed = [False] * n #记录所在岛屿是否封闭
def find(self, x) :
if self.parent[x] != x :
self.parent[x] = self.find(self.parent[x])
return self.parent[x]
def merge(self, x, y) :
px, py = self.find(x), self.find(y)
#两个同属一个岛屿直接返回,否则进行合并
if px == py :
return
#小岛合并到大岛,为了提高查找的效率
if self.size[px] > self.size[py] :
self.parent[py] = px
self.size[px] += self.size[py]
self.isClosed[px] &= self.isClosed[py]
else :
self.parent[px] = py
self.size[py] += self.size[px]
self.isClosed[py] &= self.isClosed[px]
#每增加一新陆地需要进行更新parent
def updateParent(self, x, closed) :
if self.parent[x] == -1 :
self.parent[x] = x
self.size[x] = 1
self.isClosed[x] = closed
class Solution:
def solve(self, board: List[List[str]]) -> None:
m, n = len(board), len(board[0])
uf = UnionFind(m * n)
for i in range(m) :
for j in range(n) :
if board[i][j] == 'O' :
close = True if (i > 0 and i < m - 1 and j > 0 and j < n - 1 ) else False
uf.updateParent(i * n + j, close)
if i - 1 >= 0 and board[i - 1][j] == 'O' :
uf.merge(i * n + j, (i - 1) * n + j )
if j - 1 >= 0 and board[i][j - 1] == 'O' :
uf.merge(i * n + j, i * n + j - 1)
for i in range(m) :
for j in range(n) :
if board[i][j] == 'O' and uf.isClosed[uf.find(i * n + j)] == True:
board[i][j] = 'X'