每日一题 由斜杠划分区域 LeetCode959

69 篇文章 0 订阅
44 篇文章 0 订阅

并查集问题,把每个单元格看作是四个小三角形,然后对各个小三角形进行合并。

// 每一个单元格可以分为四个小单元格,然后根据每个位置的字符进行单元格内合并或单元格间合并

class UnionFind {
public:
    UnionFind(int n): f(n), count(n) {
        for (int i = 0; i < n; ++i) {
            f[i] = i;
        }
    }

    int findf(int x) {
        if (f[x] != x) {
            f[x] = findf(f[x]);
        }
        return f[x];
    }

    void unionMerge(int x, int y) {
        int fx = findf(x), fy = findf(y);
        if (fx == fy) return;
        f[fy] = fx;
        count--;
    }

    int getCount() {
        return count;
    }

private:
    vector<int> f;
    int count;
};

class Solution {
public:
    int regionsBySlashes(vector<string>& grid) {
        int gridNums = grid.size();
        int traingleSize = 4 * gridNums * gridNums;

        UnionFind uf(traingleSize);
        for (int i = 0; i < gridNums; ++i) {
            for (int j = 0; j < gridNums; ++j) {
                int index = 4 * (i * gridNums + j);
                char c = grid[i][j];

                // 先进行单元间合并
                if (c == ' ') {
                    // 空格,0123全部合并
                    uf.unionMerge(index, index + 1);
                    uf.unionMerge(index, index + 2);
                    uf.unionMerge(index, index + 3);
                }
                else if (c == '/') {
                    // 斜杠,合并01和23
                    uf.unionMerge(index, index + 1);
                    uf.unionMerge(index + 2, index + 3);
                }
                else if (c == '\\') {
                    // 反斜杠,合并12和03
                    uf.unionMerge(index + 1, index + 2);
                    uf.unionMerge(index, index + 3);
                }

                // 再进行单元格间合并,扫描每一个单元格右边和下边的单元格,将每个单元格的第2个三角和右边第0个合并,第3个三角和下边第1个三角合并
                if (j < gridNums - 1) { // 先扫描右边
                    uf.unionMerge(index + 2, 4 * (i * gridNums + j + 1));
                }
                if (i < gridNums - 1) { // 再扫描左边
                    uf.unionMerge(index + 3, 4 * ((i + 1) * gridNums + j) + 1);
                }
            }
        }
        return uf.getCount();
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值