Leetcode959. 由斜杠划分区域

959. 由斜杠划分区域

Difficulty: 中等

在由 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] 是 '/''\'、或 ' '

Solution

思路:题意是说可以通过''和'/'或空格对一个NN的正方形进行分割。看了题解知道可以等价转化为判断连通图,那么可以直接使用并查集。NN的正方形由N*N个小正方形组成,每个小正方形沿对角线可以分成四份三角形。我们要做的就是判断这四份三角形是否连通(可能被‘/’或''给分割了)。注意,每个相邻的小正方形与隔壁小正方形是连通的。

Language: java

​class Solution {
    public int regionsBySlashes(String[] grid) {
        int len = grid.length;
        UnionFind uf = new UnionFind(4*len*len);
      /*
      *      将小正方形分为四份,编号顺序为上右下左,依次是i,i+1,i+2,i+3
      *      遍历小正方形,根据'\'或'/'或' '合并并查集
      */
        for(int i=0; i<len; i++){
            int ii = i * len * 4;
            for(int j=0; j<len; j++){
                switch(grid[i].charAt(j)){
                    case ' ':
                        uf.merge(ii+j*4,ii+j*4+1,ii+j*4+2,ii+j*4+3);
                        break;
                    case '\\':
                        uf.merge(ii+j*4, ii+j*4+1);
                        uf.merge(ii+j*4+2, ii+j*4+3);
                        break;
                    case '/':
                        uf.merge(ii+j*4, ii+j*4+3);
                        uf.merge(ii+j*4+1,ii+j*4+2);
                        break;
                }
                  /*
                  *      每个三角形都与邻边的小正方形相通
                  */
                if(j != 0) uf.merge(ii+(j-1)*4+1, ii+j*4+3);
                if(i != 0) uf.merge(ii-len*4+j*4+2, ii+j*4);
            }
        }
        Set<Integer> set = new HashSet<>();
        for(int i=0; i<4*len*len; i++){
            set.add(uf.find(i));
        }
        return set.size();
    }

    class UnionFind{
        int[] parent;
        public UnionFind(int n){
            parent = new int[n];
            for(int i=0; i<n; i++) parent[i] = i;
        }

        public int find(int i){
            return i == parent[i] ? i : (parent[i] = find(parent[i]));
        }
        public void merge(int i, int j){
            parent[find(j)] = find(i);
        }
        public void merge(int...nums){
            for(int i=1; i<nums.length; i++){
                merge(nums[0], nums[i]);
            }
        }
    }
}

PS:为啥最近的题都是并查集!?!?

上一篇:从 回归(简述) 到 广义线性模型


下一篇:C++-POJ1017-Packets