# 0827. Making A Large Island ###### tags: `Leetcode` `FaceBook` `Hard` `Union Find` `Island` Link: https://leetcode.com/problems/making-a-large-island/ ## 思路 并查集先合并所有island,然后遍历所有水域,对于每一个水域上下左右如果有岛,并且father不同,那么这些岛的面积求和+1,就是现在的岛屿面积 这里要注意的是一开始合并的时候因为是用边合并,所以这种状况是考虑不到单个一个点的island的,所以 ``` fa[i] = i size[i] = grid[i/C][i%C]==1?1:0 ``` 保证每个节点都记录下来 其次要注意并查集的两个function - combine function里面不要漏掉如果两个父节点相同,直接return - find function里面最后```return fa[a] = find(fa[a])```而不是```fa[a] = find(a)``` - 然后由于原本的方法没有考虑到没有水的情况(不用合并,直接拿最大岛屿),所以加上了第30行```maxArea = Math.max(maxArea, size[i*C+j]);``` - 第40行```if(!father.contains(find(nei)))```一定不能写```if(!father.contains(nei))```debug很久才找到 ## Code ```java= class Solution { private int[] fa, size; public int largestIsland(int[][] grid) { int R = grid.length; int C = grid[0].length; fa = new int[R*C]; size = new int[R*C]; for(int i = 0;i < R*C;i++){ fa[i] = i; size[i] = grid[i/C][i%C]==1?1:0; } for(int i = 0;i < R;i++){ for(int j = 0;j < C;j++){ if(grid[i][j] == 1){ if(j+1<C && grid[i][j+1] == 1){ combine(grid, i*C+j, i*C+j+1); } if(i+1<R && grid[i+1][j] == 1){ combine(grid, i*C+j, (i+1)*C+j); } } } } int maxArea = 0; for(int i = 0;i < R;i++){ for(int j = 0;j < C;j++){ if(grid[i][j] == 0){ maxArea = Math.max(maxArea, getArea(i,j,grid)); } maxArea = Math.max(maxArea, size[i*C+j]); } } return maxArea; } private int getArea(int x, int y, int[][] grid){ List<Integer> neighbor = getneighbor(x,y,grid); Set<Integer> father = new HashSet<>(); int area = 0; for(int nei:neighbor){ if(!father.contains(find(nei))){ father.add(find(nei)); area+=size[find(nei)]; } } return area+1; } private List<Integer> getneighbor(int x, int y, int[][] grid){ int R = grid.length; int C = grid[0].length; List<Integer> ans = new ArrayList<>(); if(x-1>=0 && grid[x-1][y]==1) ans.add((x-1)*C+y); if(x+1<R && grid[x+1][y]==1) ans.add((x+1)*C+y); if(y-1>=0 && grid[x][y-1]==1) ans.add(x*C+y-1); if(y+1<C && grid[x][y+1]==1) ans.add(x*C+y+1); return ans; } private int find(int a){ if(fa[a] == a) return a; else return fa[a] = find(fa[a]); } private void combine(int[][] grid, int a, int b){ a = find(a); b = find(b); if(a == b) return; if(size[a]<size[b]){ fa[a] = b; size[b]+=size[a]; } else{ fa[b] = a; size[a]+=size[b]; } } } ```