In a 2D grid of 0s and 1s, we change at most one 0 to a 1.
After, what is the size of the largest island? (An island is a 4-directionally connected group of 1s).
Example
Example 1:
Input:[[1, 0], [0, 1]]
Output:3
Explanation:
Change one 0 to 1 and connect two 1s, then we get an island with area = 3.
Example 2:
Input: [[1, 1], [1, 0]]
Output:4
Explanation:
Change the 0 to 1 and make the island bigger, only one island with area = 4.
Example 3:
Input:[[1, 1], [1, 1]]
Output:4
Explanation:
Can't change any 0 to 1, only one island with area = 4.
Notice
- 1 <= grid.length = grid[0].length <= 50.
- 0 <= grid[i][j] <= 1.
Code (Java):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | public class Solution { /** * @param grid: * @return: nothing */ public int largestIsland( int [][] grid) { // if (grid == null || grid.length == 0 ) { return 0 ; } int m = grid.length; int n = grid[ 0 ].length; UF uf = new UF(m, n, grid); int [][] dirs = {{- 1 , 0 }, { 1 , 0 }, { 0 , - 1 }, { 0 , 1 }}; // step 1: connect all 1s for ( int i = 0 ; i < m; i++) { for ( int j = 0 ; j < n; j++) { for ( int [] dir : dirs) { int nx = i + dir[ 0 ]; int ny = j + dir[ 1 ]; if (grid[i][j] == 1 && nx >= 0 && nx < m && ny >= 0 && ny < n && grid[nx][ny] == 1 ) { uf.union(i * n + j, nx * n + ny); } } } } int maxSize = 0 ; // step 2: find all 0s and try to connect for ( int i = 0 ; i < m; i++) { for ( int j = 0 ; j < n; j++) { int size = 1 ; Set<Integer> parents = new HashSet<>(); for ( int [] dir : dirs) { int nx = i + dir[ 0 ]; int ny = j + dir[ 1 ]; if (grid[i][j] == 0 && nx >= 0 && nx < m && ny >= 0 && ny < n && grid[nx][ny] == 1 ) { int parent = uf.getParent(nx * n + ny); if (!parents.contains(parent)) { parents.add(parent); size += uf.getSize(nx * n + ny); } } } maxSize = Math.max(size, maxSize); } } return maxSize; } } class UF { int [] parents; int [] size; int m; int n; int [][] grid; public UF ( int m, int n, int [][] grid) { this .m = m; this .n = n; this .grid = grid; parents = new int [m * n]; size = new int [m * n]; for ( int i = 0 ; i < m; i++) { for ( int j = 0 ; j < n; j++) { parents[i * n + j] = i * n + j; size[i * n + j] = 1 ; } } } public void union( int a, int b) { int pa = find(a); int pb = find(b); if (pa != pb) { parents[pa] = pb; size[pb] += size[pa]; } } private int find( int a) { int root = a; while (root != parents[root]) { root = parents[root]; } // path compression while (root != a) { int parent = parents[a]; parents[a] = root; a = parent; } return root; } public int getSize( int a) { int pa = find(a); return size[pa]; } public int getParent( int a) { return find(a); } } |
No comments:
Post a Comment