并查集解决被围绕的区域

并查集


public class Solution {
    //并查集
 private static class UnionFind{
        int[] parents; 
        UnionFind(int size){
            parents = new int[size];
           //并查集数组初始化
           for(int i = 0; i < size; i++){
               parents[i] = i;
           }
        }

        public int find(int x){
            int r = x;
            while(parents[r] != r){
              
                r = parents[r];
            }
            return r;
        }

        public void union(int x, int y){
            int fx = find(x);
            int fy = find(y);
            if(fx == fy){
                return;
            }
            parents[fx] = fy;
        }

        public boolean isConnect(int x, int y){
            return find(x) == find(y);
        }

    }


    public void solve(char[][] board) {

        int m = board.length;
        if(m == 0){
            return ;
        }
        int n = board[0].length;

        //引入虚拟节点,是所有边缘0节点的父节点 序号为 m*n
        int dummy = m * n;
        UnionFind uf = new UnionFind(m * n + 1);
        for(int i = 0; i < m; i++){
            for(int j = 0; j < n; j++){
                if(board[i][j] == 'O'){
                    if(i == 0 || i == m - 1 || j == 0 || j == n - 1){//边缘的 O
                        uf.union(i * n + j, dummy);
                    }else{//非边缘的o
                        if(i > 0 && board[i - 1][j] == 'O'){
                          uf.union(i * n + j, (i-1) * n + j);
                        }
                        if(i < m - 1 && board[i + 1][j] =='O'){
                            uf.union(i * n + j, (i+1) * n + j);
                        }
                        if(j  > 0 && board[i][j - 1] =='O'){
                            uf.union(i * n + j, i * n + (j - 1));
                        }
                        if(j < n - 1 && board[i][j + 1] =='O'){
                            uf.union(i * n + j, i * n + (j + 1));
                        }
                    }
                }

                
            }
        }


        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (uf.isConnect(i * n + j, dummy)) {
                    // 和dummy 在一个连通区域的,那么就是O
                    board[i][j] = 'O';
                } else {
                    board[i][j] = 'X';
                }
            }
        }

    }

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值