被包围的区域 surrounded-regions
题目描述
现在有一个仅包含‘X’和‘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
Given a 2D board containing’X’and’O’, capture all regions surrounded by’X’.
A region is captured by flipping all’O’s into’X’s in that surrounded region .
For example,
X X X X
X O O X
X X O X
X O X X
After running your function, the board should be:
X X X X
X X X X
X X X X
X O X X
解题思路
- DFS:
- 所有与四条边相连的O都保留,其他O都变为X
- 遍历四条边上的O,并深度遍历与其相连的O,将这些O都转为*
- 将剩余的O变为X
- 将剩余的*变为O
- 此题用不到回溯,因为不需要记录路径,仅需要在到达每一个位置时改变元素的值,所以用DFS就可以解决。
- 回溯法和DFS的关系:
回溯法是求问题的解,使用的是DFS(深度优先搜索)。在DFS的过程中发现不是问题的解,那么就开始回溯到上一层或者上一个节点。DFS是遍历整个搜索空间,而不管是否是问题的解。所以更觉得回溯法是DFS的一种应用,DFS更像是一种工具。
class Solution {
public:
int rowNum, colNum;
void solve(vector<vector<char>> &board) {
if(board.size() == 0 || board[0].size() == 0) return ;
rowNum = board.size();
colNum = board[0].size();
//将与上下两边的O相邻的所有O全变成*
for(int i = 0; i < colNum; i ++) {
dfs(board, 0, i); //遍历上边的O
dfs(board, rowNum - 1, i); //遍历下边的O
}
//将与左右两边的O相邻的所有O全变成*
for(int i = 0; i < rowNum; i ++) {
dfs(board, i, 0); //遍历左边的O
dfs(board, i, colNum - 1); //遍历右边的O
}
for(int i = 0; i < rowNum; i ++) {
for(int j = 0; j < colNum; j ++) {
if(board[i][j] == '*') {
board[i][j] = 'O';
} else if(board[i][j] == 'O') {
board[i][j] = 'X';
}
}
}
}
//将坐标为row,col上的O相邻的所有O全变成*
void dfs(vector<vector<char>> &board, int row, int col) {
if(board[row][col] == 'O') {
board[row][col] = '*';
if(row > 0) dfs(board, row - 1, col); //往上
if(row < rowNum - 1) dfs(board, row + 1, col); //往下
if(col > 0) dfs(board, row, col - 1); //往左
if(col < colNum - 1) dfs(board, row, col + 1); //往右
}
}
};