leecode.959.由斜杠划分区域

题目

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

示例一

输入:
[
" /",
"/ "
]
输出:2
解释:2x2 网格如下:
在这里插入图片描述

思路分析

  • 对于一个1*1的小方格来说,我们根据斜杠的方向相当于将其划分成了四个区域,如下图所示。对于合并来说,分为块内的合并和块间的合并。对于块内的合并,如果采用’/‘那么合并的是1,2和0,3;如果采用的是’’,合并的是0,1和2,3.对于块间的合并来说,如果采用’/‘那么合并的是1,2本来都是一个整体了,此时我们需要考虑的是1和右边的块0,2和下边的块0;如果采用的是’’,合并的是0,1本来都是一个整体了,此时我们需要考虑的是1和右边的块0,0和上边的块2。所以总的来说,需要考虑的是本块的1和右边的块3,本块的块2和下面的块0.
    在这里插入图片描述

代码

class unionSet{
    private:
        vector<int> parent;
        int count;
    public:
        void getParent(){
            for(int i = 0;i < parent.size();i++) cout<<parent[i]<<" ";
            cout<<endl;
        }
        unionSet(int n){
            int total = 4 * n * n;
            count = total;
            parent = vector<int> (total , 0);
            for(int i = 0;i < total;i++) parent[i] = i;
        }
        int find(int x){
            if(x == parent[x]) return x;
            return parent[x] = find(parent[x]);
           
        }
        void merge(int x, int y){
            int rootx = find(x);
            int rooty = find(y);
            if(rootx == rooty){
                return;
            }
            parent[rootx] = rooty;
            count--;
        }
        int getCount(){
            return count;
        }
};
class Solution {
public:
    int regionsBySlashes(vector<string>& grid) {
        int n = grid.size();
        unionSet s = unionSet(n);
        // s.getParent();
        for(int i = 0;i < n;i++){
            for(int j = 0;j < n;j++){
                int tot = 4 * (i * n + j);
                char c = grid[i][j];
                if(c == '/'){//合并0,3;合并1,2
                    s.merge(tot, tot + 3);
                    s.merge(tot + 1, tot + 2);
                }else if(c == '\\'){//合并0,1;合并2,3
                    s.merge(tot, tot + 1);
                    s.merge(tot + 2, tot + 3);
                }else{
                    s.merge(tot, tot + 1);
                    s.merge(tot + 1, tot + 2);
                    s.merge(tot + 2, tot + 3);
                }
                // cout<<"==========================="<<endl;
                // s.getParent();
                if(j + 1 < n){
                    s.merge(tot + 1, 4 * (i * n + j + 1) + 3);
                }
                // s.getParent();
                if(i + 1 < n){
                    s.merge(tot + 2, 4 * ((i + 1) * n + j));
                }
                // s.getParent();
                // cout<<"==========================="<<endl;
            }
        }
        return s.getCount();
    }
};





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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值