解题思路
思路就是将n*n
的字符对应到一个(n+1)(n+1)
的网格中,
第一步将所有边界点通过并查集连接,表示最外层这些点围成了一个区域,
如果接下来连接的点中,已经相连的,则区域数+1,否则将其两点相连.
代码
class Solution {
public int regionsBySlashes(String[] grid) {
int res = 1;
int n = grid.length;
int x = (n + 1) * (n + 1);
int[] f = new int[x];
Union uf = new Union(x);
//将边界全部连通
for (int i = 0; i < n; i++) {
//上边界
uf.unite(i, i + 1);
//下边界
uf.unite(x - n - 1 + i, x - n + i);
//左边界
uf.unite(i * (n + 1), (i + 1) * (n + 1));
//右边界
uf.unite(i * (n + 1) + n, (i + 1) * (n + 1) + n);
}
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[i].length(); j++) {
if (grid[i].charAt(j) == ' ') {
continue;
} else if (grid[i].charAt(j) == '/') {
int[] arr = getPositionOne(i, j, n);
if(uf.connected(arr[0],arr[1]))res++;
else uf.unite(arr[0], arr[1]);
} else if (grid[i].charAt(j) == '\\') {
int[] arr = getPositionTwo(i, j, n);
if(uf.connected(arr[0],arr[1]))res++;
else uf.unite(arr[0], arr[1]);
}
}
}
return res;
}
//副对角线坐标转换
private static int[] getPositionOne(int x, int y, int n) {
int[] pos1 = new int[]{x, y + 1};
int[] pos2 = new int[]{x + 1, y};
int realVal1 = pos1[0] * (n + 1) + pos1[1];
int realVal2 = pos2[0] * (n + 1) + pos2[1];
return new int[]{realVal1, realVal2};
}
//主对角线坐标转换
private static int[] getPositionTwo(int x, int y, int n) {
int[] pos1 = new int[]{x, y};
int[] pos2 = new int[]{x + 1, y + 1};
int realVal1 = pos1[0] * (n + 1) + pos1[1];
int realVal2 = pos2[0] * (n + 1) + pos2[1];
return new int[]{realVal1, realVal2};
}
}
class Union {
int[] f;
//孩子个数
int[] size;
//连通分量个数
int setCount;
int n;
void swap(int x, int y, int[] size) {
size[x] = size[x] ^ size[y];
size[y] = size[x] ^ size[y];
size[x] = size[x] ^ size[y];
}
public Union(int n) {
this.n = n;
this.f = new int[n];
this.size = new int[n];
this.setCount = n;
for (int i = 0; i < n; i++) f[i] = i;
Arrays.fill(size, 1);
}
int find(int x) {
if (x == f[x]) return x;
return f[x] = find(f[x]);
}
boolean unite(int x, int y) {
x = find(x);
y = find(y);
if (x == y) return false;
if (size[x] < size[y]) swap(x, y, size);
f[y] = x;
size[x] += size[y];
--setCount;
return true;
}
boolean connected(int x, int y) {
return find(x) == find(y);
}
}