130. 被围绕的区域
难度:中
题目概述:找到所有被包围的区域,并更改其坐标值。
thicky:题目解释中说,边界的0不会被填充。所以这道题并不是找被包围的区域,而是找的不能被包围的区域。
不能被包围的区域则必然是从矩形的边界为起点。
题解1:DFS
1)将边界的O为起点,搜索与其相连的O,统一记录为F,代表false,即不被包围。
2)全图中,除了F以外,其余的O均被包围,需要改为。
3)DFS流程和标准模板一致。
class Solution {
public:
void solve(vector<vector<char>>& board) {
if (board.empty() || board[0].empty()) return;
int row = board.size(), col = board[0].size();
for (int i = 0; i < row; ++i) {
for (int j = 0; j < col; ++j) {
if (i == 0 || i == row - 1 || j == 0 || j == col - 1) {
if (board[i][j] == 'O') dfs(board, i , j);
}
}
}
for (int i = 0; i < row; ++i) {
for (int j = 0; j < col; ++j) {
if (board[i][j] == 'O') board[i][j] = 'X';
if (board[i][j] == 'F') board[i][j] = 'O';
}
}
}
void dfs(vector<vector<char>> &board, int x, int y) {
int row = board.size(), col = board[0].size();
vector<vector<int>> dir{{0,-1},{-1,0},{0,1},{1,0}};
board[x][y] = 'F';
for (int i = 0; i < dir.size(); ++i) {
int dx = x + dir[i][0], dy = y + dir[i][1];
if (dx >= 0 && dx < row && dy >= 0 && dy < col && board[dx][dy] == 'O') {
dfs(board, dx, dy);
}
}
}
};
题解2:BFS
1)将边界的O为起点,搜索与其相连的O,统一记录为F,代表false,即不被包围。
2)思路和DFS的一样,只不过操作手法采用了BFS。
class Solution {
public:
void solve(vector<vector<char>>& board) {
if (board.empty() || board[0].empty()) return;
vector<vector<int>> dir = {{1,0},{0,-1},{-1,0},{0,1}};
int row = board.size(), col = board[0].size();
for (int i = 0; i < row; ++i) {
for (int j = 0; j < col; ++j) {
if (i != 0 && i != row - 1 && j != 0 && j != col - 1) continue;
if (board[i][j] != 'O') continue;
board[i][j] = 'F';
queue<pair<int,int>> q;
q.push({i, j});
while (!q.empty()) {
pair<int,int> cur = q.front(); q.pop();
int x = cur.first, y = cur.second;
for (int i = 0; i < dir.size(); i++) {
int x = cur.first + dir[i][0];
int y = cur.second + dir[i][1];
if (x > 0 && x < row - 1 && y > 0 && y < col - 1 && board[x][y] == 'O') {
board[x][y] = 'F';
q.push({x, y});
}
}
}
}
}
for (int i = 0; i < row; ++i) {
for (int j = 0; j < col; ++j) {
if (board[i][j] == 'O') board[i][j] = 'X';
if (board[i][j] == 'F') board[i][j] = 'O';
}
}
}
};