LeetCode959. 由斜杠划分区域

在由 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 <= grid.length == grid[0].length <= 30
grid[i][j] 是 ‘/’、’’、或 ’ '。

思路:

将一个网格分成四个部分,分别按照自己的喜好编码0、1、2、3,根据不同的分割线,每个被分割的网格都作为孤立的点,分割后的网格根据不同的分割线,通过并查集连接。

代码:

class Solution {
    int[] parents;
    int count;
    public int regionsBySlashes(String[] grid) {
        int len = grid.length;
        int dsCount = 4 * len * len;
        init(dsCount);
        for(int i = 0; i < len; i++){
            char[] ch = grid[i].toCharArray();
            for(int j = 0; j < len; j++){
                int index = 4 * (i * len + j);

                if(ch[j] == '\\'){
                    // 如果分割线是 \ 则0 1, 3 2是分别连通的
                    union(index,index + 1);
                    union(index + 2, index + 3);
                }else if(ch[j] == '/'){
                    // 如果分割线是 / 则0 3, 1 2是分别连通的
                    union(index, index + 3);
                    union(index + 1, index + 2);
                }else{
                 // 如果是空格,则整体连通
                    union(index, index + 1);
                    union(index, index + 2);
                    union(index, index + 3);
                }

                // 方格间合并
                if(j - 1 > 0){
                    // 当前方格的3与左边方格的1合并
                    union(index + 3, index - 4 + 1);
                }
                if(j + 1 < len){
                    // 当前方格的1与右边方格的3合并
                    union(index + 1, index + 4 + 3);
                }
                if(i - 1 > 0){
                    // 当前方格的0与上边方格的0合并
                    union(index, index - 4 * len + 2);
                }
                if(i + 1 < len){
                    // 当前方格的2与下边方格的0合并
                    union(index + 2, index + 4 * len);
                }
            }
        }
        return count;
    }

    public void init(int n){
        parents = new int[n];
        count = n;
        for(int i = 0; i < n; i++){
            parents[i] = i;
        }
    }

    public int find(int x){
        if(parents[x] != x){
            parents[x] = find(parents[x]);
        }
        return parents[x];
    }

    public void union(int x, int y){
        int rootX = find(x);
        int rootY = find(y);
        if(rootX != rootY){
            parents[rootY] = rootX;
            count--;
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值