在由 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] 是 '/'、'\'、或 ' '。
思路:
1.区域连接求数量的问题用并查集解决
2.大方块由N * N的个小方块组成,将小方块按照双线划分顺时针分为0,1,2,3 共4个区域
3.当‘/’时,小方块的 0,3 区域连接, 1,2区域连接
当‘\’时 ,小方块的 0,1区域连接,2,3区域连接
当‘ ’时,小方块4个区域连接
4.当然小方块和小方块之间也是相连的。
代码:
class Solution_959 {
public int regionsBySlashes(String[] grid) {
int N = grid.length;
Merge merge = new Merge(4 * N * N);
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
int root = 4 * (i * N + j);
char val = grid[i].charAt(j);
//合并内部区域
if (val != '\\') {
merge.union(root + 0, root + 1);
merge.union(root + 2, root + 3);
}
if (val != '/') {
merge.union(root + 0, root + 3);
merge.union(root + 1, root + 2);
}
//合并周边区域 (上下左右)
if (i - 1 >= 0) {
merge.union(root + 1, root - (4 * N) + 3);
}
if (i + 1 < N) {
merge.union(root + 3, root + (4 * N) + 1);
}
if (j - 1 >= 0) {
merge.union(root + 0, root - 4 + 2);
}
if (j + 1 < N) {
merge.union(root + 2, root + 4 + 0);
}
}
}
//有多少个根节点等于它自身,就有多少个区域
int ans = 0;
for (int i = 0; i < merge.parent.length; i++) {
if (merge.parent[i] == i) {
ans++;
}
}
return ans;
}
class Merge {
int[] parent;
public Merge(int num) {
parent = new int[num];
for (int i = 0; i < num; i++) {
parent[i] = i;
}
}
public int find(int x) {
if (parent[x] != x) {
return find(parent[x]);
}
return parent[x];
}
public void union(int x, int y) {
parent[find(x)] = find(y);
}
}
}