827. 最大人工岛(并查集,dfs)

class Solution {
    int[] p;
    int[] s;
    public int largestIsland(int[][] grid) {
        if(grid.length == 0) return 0;
        int n = grid.length, m = grid[0].length;
        p = new int[n*m];
        s = new int[n*m];
        for(int i = 0; i < n * m; i++) {
            p[i] = i;
            s[i] = 1;
        }
        int sum = 0;
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < m; j++) {
                if(grid[i][j] == 0) continue;
                sum++;
                if(i < n - 1) {
                    if(grid[i+1][j] == 1) {
                        int x = get(i,j,m), y = get(i+1,j,m);
                        int fx = find(x), fy = find(y);
                        if(fx != fy) {
                            p[fy] = fx; // 注意合并  向右向下两个方向合并,合并到之前
                            s[fx] += s[fy];
                        }
                    }
                }
                if(j < m - 1) {
                    if(grid[i][j+1] == 1) {
                        int x = get(i,j,m), y = get(i,j+1,m);
                        int fx = find(x), fy = find(y);
                        if(fx != fy) {
                            p[fy] = fx;
                            s[fx] += s[fy];
                        }
                    }
                }
            }
        }
        int[][] dir = {{-1,0},{0,-1},{1,0},{0,1}};
        int res = 0;
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < m; j++) {
                if(grid[i][j] == 1) continue;
                HashSet<Integer> set = new HashSet<>();
                int inf = 0;
                for(int k = 0; k < 4; k++) {
                    int x = i + dir[k][0], y = j + dir[k][1];
                    if(x < 0 || x >= n || y < 0 || y >= m || grid[x][y] == 0) {
                        set.add(--inf);
                        continue;
                    }
                    set.add(find(get(x,y,m)));
                }
                int ans = 0;
                for(int e : set) if(e >= 0) ans += s[e];
                res = Math.max(res,ans+1);
            }
        }
        return res == 0 ? sum : res;
    }
    public int find(int x) {
        if(x != p[x]) p[x] = find(p[x]);
        return p[x];
    }
    public int get(int i, int j, int m) {
        return i * m + j;
    }

}

 

posted @ 2020-09-02 11:03  Sexyomaru  阅读(131)  评论(0编辑  收藏  举报