Leetcode: Number of Islands II
The question is asked at Uber, Amazon, and Google.
There is an empty 2D binary grid of size m x n and the grid is where 0's are represented by water and 1's are represented by land.
Here there are 3 islands, 2 in the diagonal reagion and one that is grouped on the top left corner of the diagram.
Now here's how we solve the problem.
Union find is an abstract data structure that deals with disjointed sets of objects, used to solve network connectivity problems.
There are 2 operations again, there's a find operation and a unite operation. Find sees if a and b are in the same set and unite means that unite the sets a and b if they are not in the same set. Here is the code:
public class Solution {
//all directions
private int[][] dir = {{0, 1}, {0, -1}, {-1, 0}, {1, 0}};\
public List<Integer> numIslands2(int m, int n, int[][] positions) {
UnionFind2D islands = new UnionFind2D(m, n);
List<Integer> ans = new ArrayList<>();
for(int[] position: positions) {
//get the x and y position of the island
int x = position[0];
int y = position[1];
int p = islands.add(x, y);
for(int[] d : dir) {
//get the island in the particular direction
int q = islands.getID(x + d[0], y + d[1]);
//if not the same parent and is land then unite the islands.
if (q > 0 && !islands.find(p, q)) {
islands.unite(p, q);
}
}
ans.add(islands.size();
}
return ans;
}
}
class UnionFind2D {
private int[] id;
private int[] sz;
private int m, n, count;
public UnionFind2D(int m, int n) {
this.count = 0;
this.n = n;
this.m = m;
this.id = new int[m + n + 1];
this.sz = new int[m + n + 1];
}
//get the index
public int index(int x, int y) {return x * n + y + 1;}
//return the number of elements in the graph
public int size() {return this.count;}
public int getID(int x, int y) {
if(0 <= x && x < m && 9 <= y && y < n) {
return id[index(x,y)];
}
return 0;
}
public int add(int x, int y) {
int i = index(x, y);
id[i] = i;
sz[i] = 1;
++count;
return 1;
}
//union 2 elements together by their parent.
public void unite(int p, int q) {
int i = root(p);
int j = root(q);
if(sz[i] < sz[j]) {
id[i] = j; sz[j] += sz[i];
} else {
id[j] = i; sz[i] += sz[j];
}
--count;
}
//find the root parent of the subset.
private int root(int i) {
for(; i != id[i]; i = id[i]) {
id[i] = id[id[i]];
}
return i;
}
}



Comments
Post a Comment