题目描述:
在由 1 x 1 方格组成的 N x N 网格 grid 中,每个 1 x 1 方块由 /、\ 或空格构成。这些字符会将方块划分为一些共边的区域。
(请注意,反斜杠字符是转义的,因此 \ 用 “\” 表示。)。
返回区域的数目。
提示:
1 <= grid.length == grid[0].length <= 30
grid[i][j] 是 ‘/’、’’、或 ’ '。
没想出来,参考这篇博客添加链接描述
代码:
class Solution {
public int regionsBySlashes(String[] grid) {
int result = 0;
int len = grid.length;
if(len == 0){
return 0;
}
int graph[][] = new int[len * 3][len * 3];
for (int i = 0; i < len; i++) {
for (int j = 0; j < len; j++) {
if(grid[i].charAt(j) == '\\'){
graph[i * 3][j * 3] = 1;
graph[i * 3 + 1][j * 3 + 1] = 1;
graph[i * 3 + 2][j * 3 + 2] = 1;
}else if (grid[i].charAt(j) == '/') {
graph[i * 3 + 2][j * 3] = 1;
graph[i * 3 + 1][j * 3 + 1] = 1;
graph[i * 3][j * 3 + 2] = 1;
}
}
}
// 寻找
for (int i = 0; i < graph.length; i++) {
for (int j = 0; j < graph[i].length; j++) {
if(graph[i][j] == 0){
result ++;
dfs(graph, i, j);
}
}
}
return result;
}
public void dfs(int [][] graph,int x,int y){
if(x < 0 || x >= graph.length || y < 0 || y >= graph[0].length){
return;
}
if(graph[x][y] == 1){
return ;
}
graph[x][y] = 1;
dfs(graph, x + 1, y);
dfs(graph, x - 1, y);
dfs(graph, x, y + 1);
dfs(graph, x, y - 1);
}
}
也可以使用并查集来进行
将每个1x1的块分为4个小块,并对图中每个小块依次编号(视为节点),然后根据不同的字符来合并小块,注意上下和左右合并。 最后看有几个独立的连通小块(根节点)即可
路径压缩的并查集
排名靠前的代码:
class Solution {
int count, n;
int[] f;
public int regionsBySlashes(String[] grid) {
n = grid.length;
f = new int[n*n*4];
count = n*n*4;
for (int i=0; i<count; i++) {
f[i] = i;
}
for (int i=0; i<n; i++) {
for (int j=0; j<n; j++) {
if (i>0) {
union(g(i-1,j,2), g(i,j,0));
}
if (j>0) {
union(g(i,j-1,1), g(i,j,3));
}
if (grid[i].charAt(j)!='/') {
union(g(i,j,0), g(i,j,1));
union(g(i,j,2), g(i,j,3));
}
if (grid[i].charAt(j)!='\\') {
union(g(i,j,0), g(i,j,3));
union(g(i,j,1), g(i,j,2));
}
}
}
return count;
}
private int find(int x) {
if (x != f[x]) {
f[x] = find(f[x]);
}
return f[x];
}
private void union(int x, int y) {
x = find(x); y = find(y);
if (x!=y) {
f[x] = y;
count--;
}
}
private int g(int i, int j, int k) {
return (i*n+j)*4+k;
}
}