200. 島嶼數量

wsshub發表於2024-08-09

並查集解法

class Union {
    // 用一個一維陣列表示聯通關係。記錄該陣列每個節點的父節點的位置
    int[] parent;

    int cnt = 0;

    Union(int length) {
        this.parent = new int[length];
    
    }
    // 查,且路徑壓縮。就是查詢該位置的根節點/父親是誰
    int find(int x) {
        if (parent[x] != x) {
            parent[x] = find(parent[x]);
        }
        return parent[x];
    }
    // 並,合併兩個節點所在的聯通分量
    void union(int x, int y) {
        int px = find(x);
        int py = find(y);
        //分別查詢這兩個節點的根節點,然後隨便選擇一個作為父節點
        if (px != py) {
            parent[px] = py;
            cnt--;
        }
        
    }
    // 還差一個初始化,一般parent[i]=i。本題不是每個位置都有父節點,本題的0代表不是連通圖的一部分
}

class Solution {
    public int numIslands(char[][] grid) {
       int m = grid.length;
       int n = grid[0].length; 

       Union uj = new Union(m*n);

        // 並查集的初始化
        for (int i=0; i< m; i++) {
            for (int j=0;j<n;j++) {
                if (grid[i][j]=='1') {
                    uj.parent[i*n + j] = i*n+j;
                    uj.cnt = uj.cnt+1;
                }
            }
        }
        System.out.println("##### " + uj.cnt);

        for (int i=0;i<m;i++) {
            for(int j=0;j<n;j++) {
                if (grid[i][j] == '1') {
                    grid[i][j] = '0';
                    if (i-1>=0 && grid[i-1][j]=='1') {
                        uj.union((i-1)*n+j, i*n+j);
                    }
                    if (i+1<m && grid[i+1][j] == '1') {
                        uj.union((i+1)*n+j, i*n+j);
                    }
                    if (j-1>=0 && grid[i][j-1]=='1') {
                        uj.union(i*n+j-1, i*n+j);
                    }
                    if (j+1<n && grid[i][j+1] == '1') {
                        uj.union(i*n+j+1, i*n+j);
                    }
                    
                }
            }
        }
        return uj.cnt;


    }
}

相關文章