并查集问题,把每个单元格看作是四个小三角形,然后对各个小三角形进行合并。
// 每一个单元格可以分为四个小单元格,然后根据每个位置的字符进行单元格内合并或单元格间合并
class UnionFind {
public:
UnionFind(int n): f(n), count(n) {
for (int i = 0; i < n; ++i) {
f[i] = i;
}
}
int findf(int x) {
if (f[x] != x) {
f[x] = findf(f[x]);
}
return f[x];
}
void unionMerge(int x, int y) {
int fx = findf(x), fy = findf(y);
if (fx == fy) return;
f[fy] = fx;
count--;
}
int getCount() {
return count;
}
private:
vector<int> f;
int count;
};
class Solution {
public:
int regionsBySlashes(vector<string>& grid) {
int gridNums = grid.size();
int traingleSize = 4 * gridNums * gridNums;
UnionFind uf(traingleSize);
for (int i = 0; i < gridNums; ++i) {
for (int j = 0; j < gridNums; ++j) {
int index = 4 * (i * gridNums + j);
char c = grid[i][j];
// 先进行单元间合并
if (c == ' ') {
// 空格,0123全部合并
uf.unionMerge(index, index + 1);
uf.unionMerge(index, index + 2);
uf.unionMerge(index, index + 3);
}
else if (c == '/') {
// 斜杠,合并01和23
uf.unionMerge(index, index + 1);
uf.unionMerge(index + 2, index + 3);
}
else if (c == '\\') {
// 反斜杠,合并12和03
uf.unionMerge(index + 1, index + 2);
uf.unionMerge(index, index + 3);
}
// 再进行单元格间合并,扫描每一个单元格右边和下边的单元格,将每个单元格的第2个三角和右边第0个合并,第3个三角和下边第1个三角合并
if (j < gridNums - 1) { // 先扫描右边
uf.unionMerge(index + 2, 4 * (i * gridNums + j + 1));
}
if (i < gridNums - 1) { // 再扫描左边
uf.unionMerge(index + 3, 4 * ((i + 1) * gridNums + j) + 1);
}
}
}
return uf.getCount();
}
};