开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第33天,点击查看活动详情
力扣——130. 被围绕的区域
130. 被围绕的区域
给你一个 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' 都不会被填充为 'X'。 任何不在边界上,或不与边界上的 'O' 相连的 'O' 最终都会被填充为 'X'。如果两个元素在水平或垂直方向相邻,则称它们是“相连”的。
示例 2:
输入:board = [["X"]]
输出:[["X"]]
提示:
m == board.lengthn == board[i].length1 <= m, n <= 200board[i][j]为'X'或'O'
问题解析
我们可以初始遍历一下数组,把所有的‘O’位置都记录下来,以它们为起点进行bfs。再从其中看哪些‘O'会和边界搭上边,如果没搭上边就可以把它改成’X'但是这样太麻烦了,每一个点都要bfs一遍,复杂度过高。
我们可以只遍历边界,记录在边界上的‘O'点的位置,以它们为起点进行bfs,找和它们相连的’O'。把bfs到的点都打上标记。
最后遍历一遍数组,把所有没有标记的点都变成‘X'。
AC代码
class Solution {
public:
int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};
int st[300][300];
void solve(vector<vector<char>>& board) {
queue<vector<int>>que;
int n=board.size(),m=board[0].size();
for(int i=0;i<n;i++)
{
if(board[i][0]=='O')
{
que.push({i,0});
st[i][0]=1;
}
if(board[i][m-1]=='O')
{
que.push({i,m-1});
st[i][m-1]=1;
}
}
for(int j=0;j<m;j++)
{
if(board[0][j]=='O')
{
que.push({0,j});
st[0][j]=1;
}
if(board[n-1][j]=='O')
{
que.push({n-1,j});
st[n-1][j]=1;
}
}
while(!que.empty())
{
int len=que.size();
for(int i=0;i<len;i++)
{
int x=que.front()[0],y=que.front()[1];
que.pop();
for(int j=0;j<4;j++)
{
int a=dx[j]+x,b=dy[j]+y;
if(a>=0&&a<n&&b>=0&&b<m&&st[a][b]==0&&board[a][b]=='O')
{
st[a][b]=1;
que.push({a,b});
}
}
}
}
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(board[i][j]=='O'&&st[i][j]==0)
board[i][j]='X';
}
}
}
};