130. 被围绕的区域

给定一个二维的矩阵,包含 '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;
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值