leetcode130. 被围绕的区域
给定一个二维的矩阵,包含 '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'
。如果两个元素在水平或垂直方向相邻,则称它们是“相连”的。
方法:深度优先搜索DFS
思路:
本题与岛屿数量那道题类似。
根据题意,我们要找到被包围的联通区域,然后将被包围的O
替换为X
,但是由于被包围不好判断,因此我们可以换一种思路分析。
对于所有的O,如果处于边界位置,那么与之联通的O都不需要改变,即我们把与边界O相连的这些O,当作一个“岛屿”。
因此,我们只需要遍历所有的边界,如果为O,那么进行dfs,找到与它相连通的所有O,这些O最后不需要改变;遍历完所有边界之后,我们将剩下的点都变成X即可。
dfs函数中,我们对这一点O置为A,用于标记,然后向四个方向遍历(要保证不越界),如果某个方向也为O,那么就递归,将这个方向的点进行dfs。
这样在最后遍历所有点的时候,将所有的A换回O,其余的点都为X即可。
代码:
Python3:
class Solution:
def solve(self, board: List[List[str]]) -> None:
m = len(board)
if not m:
return
n = len(board[0])
if not n:
return
# dfs的过程,将该点改为'A',然后找与它连通的,为'O'的点,dfs
def dfs(i,j):
board[i][j] = 'A'
directions = [(i-1,j),(i+1,j),(i,j-1),(i,j+1)]
for x,y in directions:
if 0 <= x < m and 0 <= y < n and board[x][y] == 'O':
dfs(x,y)
# 遍历所有的边界的点,如果为'O',则开始dfs
for i in range(m):
if i == 0 or i == m-1:
for j in range(n):
if board[i][j] == 'O':
dfs(i,j)
else:
if board[i][0] == 'O':
dfs(i,0)
if board[i][n-1] == 'O':
dfs(i,n-1)
# 最后遍历一遍矩阵,为A的,改为'O',其他的都为'X'
for i in range(m):
for j in range(n):
if board[i][j] == 'A':
board[i][j] = 'O'
elif board[i][j] == 'O':
board[i][j] = 'X'
cpp:
class Solution {
public:
int m,n;
void solve(vector<vector<char>>& board) {
m = board.size();
if (!m) return;
n = board[0].size();
if (!n) return;
for (int i = 0; i < m; ++i){
if (i == 0 || i == m-1){
for (int j = 0; j < n; ++j){
if (board[i][j] == 'O') dfs(board,i,j);
}
}
else{
if (board[i][0] == 'O') dfs(board,i,0);
if (board[i][n-1] == 'O') dfs(board,i,n-1);
}
}
for (int i = 0; i < m; ++i)
for (int j = 0; j < n; ++j){
if (board[i][j] == 'A') board[i][j] = 'O';
else board[i][j] = 'X';
}
}
void dfs(vector<vector<char>>& board,int i,int j){
board[i][j] = 'A';
if (i-1 < m && i-1 >= 0 && j < n && j >= 0 && board[i-1][j] == 'O'){
dfs(board,i-1,j);
}
if (i+1 < m && i+1 >= 0 && j < n && j >= 0 && board[i+1][j] == 'O'){
dfs(board,i+1,j);
}
if (i < m && i >= 0 && j-1 < n && j-1 >= 0 && board[i][j-1] == 'O'){
dfs(board,i,j-1);
}
if (i < m && i >= 0 && j+1 < n && j+1 >= 0 && board[i][j+1] == 'O'){
dfs(board,i,j+1);
}
}
};