並查集解法
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;
}
}