147、由斜杠划分区域

题目描述:
在由 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;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值