305. Number of Islands II

https://leetcode.com/problems/number-of-islands-ii/description/

305. Number of Islands II_第1张图片
image.png

这道题我们可以想这样一个问题,如果每丢一块石头,什么时候岛屿会加,什么时候岛屿会减,什么时候岛屿会不加不减。
把这几种情况罗列一下,我们可以发现,丢了一块石头下去。四周都是海,那么岛屿会加。如果周围有陆地,那么岛屿会根据连通的陆地块数减去对应的。那么就是要看一个集合和另一个集合能不能连通起来。我们就能想到并查集。
下面是代码

int[] parent;
    int[] rank;
    int find(int i){
        if(i == parent[i]) return i;
        return parent[i] = find(parent[i]);
    }
    boolean union(int i,int j){
        int pi = find(i);
        int pj = find(j);
        if(pi == pj) return false;
        if(rank[pi]>rank[pj]){
            parent[pj] = pi;
        }else if(rank[pj]>rank[pi]){
            parent[pi] = pj;
        }else{
            parent[pi] = pj;
            rank[pi]++;
        }
        return true;
    }
    public List numIslands2(int m, int n, int[][] positions) {
        List res = new ArrayList<>();
        parent = new int[m*n];
        rank = new int[m*n];
        Arrays.fill(parent,-1);
        int[][] dirs ={{1,0},{0,1},{-1,0},{0,-1}};
        int cnt = 0;
        for(int[] pos : positions){
            int y = pos[0];
            int x = pos[1];
            if(out(y,x,m,n) || parent[y*n+x]!=-1){
                res.add(cnt);
                continue;
            }
            parent[y*n+x]=y*n+x;
            cnt++;
            for(int[] dir : dirs){
                int ny = y+dir[0];
                int nx = x+dir[1];
                if(out(ny,nx,m,n) || parent[ny*n+nx]==-1) continue;
                if(union(y*n+x,ny*n+nx)) cnt--;
            }
            res.add(cnt);
        }
        return res;
    }
    private boolean out(int y,int x,int m,int n){
        return y<0 || x<0 || x>=n || y>=m;
    }

你可能感兴趣的:(305. Number of Islands II)