Friday, January 15, 2021

Lintcode 1391. Making A Large Island

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