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):
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