在由 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--;
}
}
}