给定一个二维的矩阵,包含 'X' 和 'O'(字母 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
解释:
被围绕的区间不会存在于边界上,换句话说,任何边界上的 'O' 都不会被填充为 'X'。 任何不在边界上,或不与边界上的 'O' 相连的 'O' 最终都会被填充为 'X'。如果两个元素在水平或垂直方向相邻,则称它们是“相连”的。
使用并查集方法,并查集可以参考https://blog.youkuaiyun.com/cx1165597739/article/details/100185231
需要注意几点,
1.尽可能的压缩路径,不然很可能会超时。因为路径太长。
2.计算集合是否是边界的时候,可以同样用根节点的状态来代表整个集合的状态。
class Solution {
public:
vector<int> pre;
vector<bool> isboard;
void solve(vector<vector<char>>& board)
{
if(board.size()==0||board[0].size()==0) return;
int width=board[0].size();
int length=int(board.size())*int(board[0].size());
pre=vector<int>(length,0);
isboard=vector<bool>(length,false);
for(int i=0;i<length;i++)
{
pre[i]=i;
int row=i/width;
int col=i%width;
if (row == 0 || (row == board.size() - 1)|| col == 0 || (col == board[0].size()-1))
{
isboard[i]=true;
}
else
isboard[i]=false;
}
for(int i=0;i<length;i++)
{
int row=i/width;
int col=i%width;
if((col+1<width)&&board[row][col]==board[row][col+1])
{
join(i,i+1);
}
if((row+1<board.size())&&board[row][col]==board[row+1][col])
{
join(i,i+width);
}
}
for(int i=0;i<length;i++)
{
int row=i/width;
int col=i%width;
if(board[row][col]=='O'&&isboard[find(i)]==false)
board[row][col]='X';
}
}
int find(int t)
{
while(pre[t]!=t)
{
pre[t]=pre[pre[t]];
t=pre[t];
}
return t;
}
void join(int x,int y)
{
int a=find(x);
int b=find(y);
if(a==b)
return ;
pre[a]=b;
if(isboard[a])
isboard[b]=true;
}
};