链接
https://leetcode-cn.com/problems/regions-cut-by-slashes/
耗时
解题:null min
题解:13 min
题意
在由 1 x 1 方格组成的 N x N 网格 grid 中,每个 1 x 1 方块由 /、\ 或空格构成。这些字符会将方块划分为一些共边的区域。
(请注意,反斜杠字符是转义的,因此 \ 用 “\” 表示。)。
返回区域的数目。
提示:
- 1 <= grid.length == grid[0].length <= 30
- grid[i][j] 是 ‘/’、’\’、或 ’ '。
思路
并没有想出思路,看题解看会的。。。
正反斜杠,把一个方格划分成 4 个区域,如下所示
\1/
2 X 0
/3\
遍历网格中的每个方格,分情况合并这几个区域即可,
- 正斜杠 “/” : 合并 1,2 合并 0,3
- 反斜杠 “\”: 合并 0,1 合并 2,3
- 空格 “ ” : 合并 0,1,2,3
并且每次遍历向右向下合并,使得多个方格连通 :合并 gird[i][j] 的 0 和 gird[i][j+1] 的 2,合并 gird[i][j] 的 3 和 gird[i+1][j] 的 1
时间复杂度: O ( n 2 ) O(n^2) O(n2)
AC代码
class Solution {
public:
constexpr static int MAXN = 10100;
int father[MAXN]; // 储存i的father父节点
int areacnt = 1;
void makeSet() {
for (int i = 0; i < MAXN; i++)
father[i] = i;
}
int findRoot(int x) { // 迭代找根节点
int root = x; // 根节点
while (root != father[root]) { // 寻找根节点
root = father[root];
}
while (x != root) {
int tmp = father[x];
father[x] = root; // 根节点赋值
x = tmp;
}
return root;
}
void Union(int x, int y) { // 将x所在的集合和y所在的集合整合起来形成一个集合。
int a, b;
a = findRoot(x);
b = findRoot(y);
if(a == b) return ;
father[a] = b; // y连在x的根节点上 或father[b] = a为x连在y的根节点上
areacnt--;
}
int regionsBySlashes(vector<string>& grid) {
int n = grid.size();
areacnt = 4*n*n;
makeSet();
for(int i = 0; i < n; ++i) {
for(int j = 0; j < n; ++j) {
int ind = 4*(i*n+j);
if(grid[i][j] == '/') { // 1 2 | 0 3
Union(ind+1, ind+2);
Union(ind+0, ind+3);
}
else if(grid[i][j] == '\\') { // 1 0 | 2 3
Union(ind+1, ind+0);
Union(ind+2, ind+3);
}
else { // 0 1 2 3
Union(ind+0, ind+1);
Union(ind+1, ind+2);
Union(ind+2, ind+3);
}
if(j+1 < n) { // j 0, j+1 2
Union(ind+0, (ind+4)+2);
}
if(i+1 < n) { // i 3, i+1 1
Union(ind+3, (ind+4*n)+1);
}
}
}
return areacnt;
}
};
/*
\1/
2 X 0
/3\
*/