题目描述
给一个 m × n 的矩阵,矩阵由字符 'X' 和 'O' 组成,捕获所有被围绕的区域。
- 连接:单元格上下左右相邻算作连接。
- 区域:全部相连的
O构成一块区域。 - 被包围:如果一块区域所有
O都不在矩阵边界,就代表被X完全包围,需要把这部分O原地修改成X。
边界上的
O一定不会被包围,和边界O连通的内部O同样不会被包围,只有完全被 X 围在里面的 O 才要替换。
注意:直接原地修改数组,不需要返回值。
做题思路
直接找被包围的O不好处理,我们逆向思考:
- 边界上的 O 一定不会被包围,所有和边界 O 连通的 O,也一定不会被包围。
- 遍历矩阵四条边界,遇到
O就做 BFS,把连通的O临时标记成.(做记号,表示这部分是安全的,不能被修改)。 - 遍历整个矩阵做还原:
- 仍然是
O:说明没有和边界连通,是被包围的,改成X - 是
.:原本是边界连通的 O,恢复回O
- 仍然是
核心:不找被包围的,先找不会被包围的,标记之后再批量修改。
class Solution {
public:
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
int m,n;
void solve(vector<vector<char>>& board) {
m=board.size();
n=board[0].size();
for(int j=0;j<n;j++)
{
if(board[0][j]=='O')
bfs(board,0,j);
if(board[m-1][j]=='O')
bfs(board,m-1,j);
}
for(int i=0;i<m;i++)
{
if(board[i][0]=='O')
bfs(board,i,0);
if(board[i][n-1]=='O')
bfs(board,i,n-1);
}
//还原
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
if(board[i][j]=='O')
board[i][j]='X';
else if(board[i][j]=='.')
board[i][j]='O';
}
}
}
void bfs(vector<vector<char>>& board,int i,int j)
{
queue<pair<int ,int>>q;
q.push({i,j});
board[i][j]='.';
while(q.size())
{
auto [a,b]=q.front();
q.pop();
for(int k=0;k<4;k++)
{
int x=a+dx[k];
int y=b+dy[k];
if(x>=0 && x<m && y>=0 && y<n && board[x][y]=='O')
{
q.push({x,y});
board[x][y]='.';
}
}
}
}
};

209

被折叠的 条评论
为什么被折叠?



