130. Surrounded Regions(被围绕的区域)
题目大意
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.
中文释义
给定一个 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’ 不应该被翻转如果它:
- 在边界上,或者
- 它相邻于不应该被翻转的 ‘O’。
底部的 ‘O’ 在边界上,所以它没有被翻转。
其他三个 ‘O’ 形成了一个被围绕的区域,所以它们被翻转了。
- 输入:
-
示例 2:
- 输入:
board = [["X"]]
- 输出:
[["X"]]
- 输入:
限制条件
m == board.length
n == board[i].length
1 <= m, n <= 200
board[i][j]
是 ‘X’ 或 ‘O’。
解题思路
使用深度优先搜索(DFS)来解决问题。首先处理边界上的 ‘O’,防止它们被错误地翻转,然后处理内部区域的 ‘O’。
步骤说明
- 初始化一个标记节点是否已访问的二维布尔数组
visited
。 - 对矩阵的左右边界进行 DFS,标记不应该翻转的 ‘O’。
- 对矩阵的上下边界进行 DFS,标记不应该翻转的 ‘O’。
- 对矩阵内部的每个节点进行 DFS:
- 如果节点是 ‘O’ 且未被标记为不翻转,则翻转它。
- 返回翻转后的矩阵。
代码
class Solution {
public:
void dfs(int i, int j, vector<vector<char>>& board, vector<vector<bool>>& visited, bool flag) {
if (i < 0 || i >= board.size() || j < 0 || j >= board[i].size()) return;
if (board[i][j] == 'X' || visited[i][j]) return;
visited[i][j] = true;
if (flag) {
board[i][j] = 'X';
}
dfs(i - 1, j, board, visited, flag);
dfs(i + 1, j, board, visited, flag);
dfs(i, j + 1, board, visited, flag);
dfs(i, j - 1, board, visited, flag);
}
void solve(vector<vector<char>>& board) {
int n = board.size(), m = board[0].size();
vector<vector<bool>> visited(n, vector<bool>(m, false));
for (int i = 0; i < n; i++) {
dfs(i, 0, board, visited, false);
dfs(i, m - 1, board, visited, false);
}
for (int j = 0; j < m; j++) {
dfs(0, j, board, visited, false);
dfs(n - 1, j, board, visited, false);
}
for (int i = 1; i < n - 1; i++) {
for (int j = 1; j < m - 1; j++) {
dfs(i, j, board, visited, true);
}
}
}
};