LeetCode每日一题 - 959. 由斜杠划分区域(并查集)

题目:959. 由斜杠划分区域

Description

在由 1 x 1 方格组成的 N x N 网格 grid 中,每个 1 x 1 方块由 /、\ 或空格构成。这些字符会将方块划分为一些共边的区域。
(请注意,反斜杠字符是转义的,因此 \ 用 “\” 表示。)。
返回区域的数目。

Sample

LeetCode每日一题 - 959. 由斜杠划分区域(并查集)_第1张图片

Solution

利用并查集求解连通分量个数。

  • 将方格分成NxN个网格,网格数等于给出字符串数组中的字符总数

将每个网格分成四个区域,如下
LeetCode每日一题 - 959. 由斜杠划分区域(并查集)_第2张图片
首先考虑单个网格内的合并
根据该网格对应的字符,进行不同的合并操作

  • 空格:合并(0,1) (1,2) (2,3)
  • 正斜杠:合并(1,2) (0,3)
  • 反斜杠:合并(0,1) (2,3)

接下来考虑相邻网格间的合并
找出可以合并的区域,乍一看,我们并不知道哪些区域是可以合并的。
当遇到一个问题,不知如何求解时,可以将所有已知的信息列出来,看看能不能从中得到些许提示。
下面是一个2x2的网格所有可能的划分的叠加。从中可以看到,左右相邻的两个网格的1区域和3区域是可以合并的,无论它们各自网格内的划分是怎样的。上下相邻的两个网格的0区域和2区域亦是如此。
LeetCode每日一题 - 959. 由斜杠划分区域(并查集)_第3张图片
网格个数更多的话,这个性质也是成立的。
LeetCode每日一题 - 959. 由斜杠划分区域(并查集)_第4张图片
不会画图,凑合着用吧

合并操作结束,求一下连通分量的个数即可。

AC Code
class Solution {
     
public:
    int len;
    int f[30*30*4];
    int find(int x){
     
        return f[x]==x?x:find(f[x]);
    }
    void meger(int x,int y){
     
        f[find(x)] = find(y);
    }
    int regionsBySlashes(vector<string>& grid) {
     
        len = grid.size();
        for(int i=0;i<len*len*4;i++){
     
            f[i]=i;
        }
        for(int i=0;i<len;i++){
     
            for(int j=0;j<len;j++){
     
                int index = i*len + j;
                //网格内合并
                if(grid[i][j]==' '){
     
                    meger(4*index,4*index+1);
                    meger(4*index+1,4*index+2);
                    meger(4*index+2,4*index+3);
                }
                else if(grid[i][j]=='/'){
     
                    meger(4*index,4*index+3);
                    meger(4*index+1,4*index+2);
                }
                else if(grid[i][j]=='\\'){
     
                    meger(4*index,4*index+1);
                    meger(4*index+2,4*index+3);
                }
                //网格间合并
                //左右
                if(j<len-1){
     
                    meger(4*index+1,4*(index+1)+3);
                }
                //上下
                if(i<len-1){
     
                    meger(4*index+2,4*(index+len));
                }
            }
        }
        set<int> s;
        for(int i=0;i<len*len*4;i++){
     
            s.insert(find(i));
        }
        return s.size();
    }
};

希望对你有帮助!

你可能感兴趣的:(LeetCode,leetcode,并查集,c++)