【算法练习】leetcode每日一题/并查集 959由斜杠划分区域

959. 由斜杠划分区域

难度中等

在由 1 x 1 方格组成的 N x N 网格 grid 中,每个 1 x 1 方块由 /\ 或空格构成。这些字符会将方块划分为一些共边的区域。

(请注意,反斜杠字符是转义的,因此 \ 用 "\\" 表示。)。

返回区域的数目。

示例 1:

输入:
[
  " /",
  "/ "
]
输出:2
解释:2x2 网格如下:

示例 2:

输入:
[
  " /",
  "  "
]
输出:1
解释:2x2 网格如下:

示例 3:

输入:
[
  "\\/",
  "/\\"
]
输出:4
解释:(回想一下,因为 \ 字符是转义的,所以 "\\/" 表示 \/,而 "/\\" 表示 /\。)
2x2 网格如下:

示例 4:

输入:
[
  "/\\",
  "\\/"
]
输出:5
解释:(回想一下,因为 \ 字符是转义的,所以 "/\\" 表示 /\,而 "\\/" 表示 \/。)
2x2 网格如下:

示例 5:

输入:
[
  "//",
  "/ "
]
输出:3
解释:2x2 网格如下:

提示:

  1. 1 <= grid.length == grid[0].length <= 30
  2. grid[i][j] 是 '/''\'、或 ' '

思路:

参考官方题解

重点的思路在于先拆分后合并

思路图如下:

写一下并查集

int findRoot(int x){
    if(tree[x]==-1){
        return x;
    }
    else {
        int tmp = findRoot(tree[x]);
        tree[x] = tmp;
        return tmp;
    }
}

//非递归形式
int findRoot1(int x){
    int tp=x;
    while(tree[x]!=-1){
        x=tree[x];
    }
    int ret=x;
    //遍历一遍进行路径压缩
    x=tp;
    while(tree[x]!=-1){
        //需要临时变量t 因为tree[x]被改变
        int t=tree[t];
        tree[x]=ret;
        x=t;
    }
    return ret;
}

如何表示对应的字符

直接用grid[i][j]即可   

grid[i][j]=='/'  字符

代码:

int tree[3660];  //N*N*4
int findRoot(int x){
    if(tree[x]==-1){
        return x;
    }
    else {
        int tmp = findRoot(tree[x]);
        tree[x] = tmp;
        return tmp;
    }
}
int Union(int a,int b,int count){
    int rootA=findRoot(a);
    int rootB=findRoot(b);
    if(rootA==rootB){
        return count;
    }
    tree[rootA]=rootB;
    count--;
    return count;
}//返回合并后根节点的数目

int regionsBySlashes(vector<string>& grid) {
    int N=grid.size();
    int count=N*N*4;
    //初始化并查集  都是独立的
    for(int i=0;i<N*N*4;i++){
        tree[i]=-1;
    }
    for(int i=0;i<N;i++){
        for(int j=0;j<N;j++){
            int index=4*(i*N+j);
            if( grid[i][j]== '/' ){
               //合并03
               count=Union(index,index+3,count);
               //合并12
                count=Union(index+1,index+2,count);
            }
            else if(grid[i][j]== '\\'){
                //合并01
                count=Union(index,index+1,count);
                //合并23
                count=Union(index+2,index+3,count);
            }
            else{  //空格
                //合并01
                count=Union(index,index+1,count);
                //合并12
                count=Union(index+1,index+2,count);
                //合并23
                count=Union(index+2,index+3,count);
            }

            //单元格间合并
            if(j+1<N){
                //向右合并
                int indexR=4*(i*N+j+1);
                count=Union(index+1,indexR+3,count);
            }
            //向下合并
            if(i+1<N){
                int indexD=4*((i+1)*N+j);
                count=Union(index+2,indexD,count);
            }

        }
    }
    return count;
}

猜你喜欢

转载自blog.csdn.net/weixin_40760678/article/details/113176181