959. 由斜杠划分区域
在由 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]
是'/'
、'\'
、或' '
。
方法一:并查集
解题思路
下图来自「官方解答」,懒得画了。
- 此题最终还是「连通性」的问题。如图所示,把每一个单元格划分成
4
个区域。 - 一共有
n = len * len * 4
个区域,其中len
为grid
的长度。 - 初始状态,
n
个单元格都没有连通,即被分为n
个区域。 - 遍历
grid
(注意:grid[i]
是字符串,我们需要遍历grid[i]
的每一个字符)- 遇到
'/'
时:连通[0]
和[3]
,连通[1]
和[2]
- 遇到
'\'
时:连通[0]
和[1]
,连通[2]
和[3]
- 遇到
' '
时:连通[0]
、[1]
、[2]
、[3]
- 遇到
- 此外,
[1]
和右边的单元格是连通的,[2]
和下方的单元格是连通的,需要分别将其连通。(因为是从左往右,从上往下遍历,所以只需处理右
和下
两个方向) - 每连通一次,区域数量
n = n - 1
,返回遍历完成后的n
参考代码
public int regionsBySlashes(String[] grid) {
int len = grid.length;
int n = len * len * 4;
UnionFind unionFind = new UnionFind(n);
for (int i = 0; i < len; i++) {
for (int j = 0; j < len; j++) {
int num = (i * len + j) * 4;
char ch = grid[i].charAt(j);
if (ch == '/') {
unionFind.union(num, num + 3);
unionFind.union(num + 1, num + 2);
} else if (ch == '\\') {
unionFind.union(num, num + 1);
unionFind.union(num + 2, num + 3);
} else {
unionFind.union(num, num + 1);
unionFind.union(num, num + 2);
unionFind.union(num, num + 3);
}
if (i < len - 1) {
unionFind.union(num + 2, num + len * 4);
}
if (j < len - 1) {
unionFind.union(num + 1, num + 7);
}
}
}
return unionFind.getCount();
}
class UnionFind {
private int[] parent;
private int count;
public UnionFind(int n) {
parent = new int[n];
count = n;
for (int i = 0; i < n; i++) {
parent[i] = i;
}
}
public void union(int x, int y) {
int rootX = find(x), rootY = find(y);
if (rootX == rootY) {
return;
}
parent[rootX] = rootY;
count--;
}
public int find(int x) {
return parent[x] == x ? parent[x] : (parent[x] = find(parent[x]));
}
public int getCount() {
return count;
}
}
执行结果