![]()
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;
}
}