Skip to content

Commit 3a425bb

Browse files
committed
Add the solution for #200
1 parent 63ae0ae commit 3a425bb

File tree

2 files changed

+143
-0
lines changed

2 files changed

+143
-0
lines changed
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
package org.sean.array;
2+
3+
/***
4+
* 200. Number of Islands
5+
*/
6+
public class IslandCounter {
7+
private int[] parent; // parent[i] = parent of i
8+
private int[] size; // size[i] = number of sites in subtree rooted at i
9+
private int count; // number of components
10+
11+
private void init(int n) {
12+
count = n;
13+
parent = new int[n];
14+
size = new int[n];
15+
for (int i = 0; i < n; i++) {
16+
parent[i] = i;
17+
size[i] = 1;
18+
}
19+
}
20+
21+
/**
22+
* The number of components.
23+
*/
24+
private int count() {
25+
return count;
26+
}
27+
28+
private int find(int p) {
29+
validate(p);
30+
while (p != parent[p])
31+
p = parent[p];
32+
return p;
33+
}
34+
35+
// validate that p is a valid index
36+
private void validate(int p) {
37+
int n = parent.length;
38+
if (p < 0 || p >= n) {
39+
throw new IllegalArgumentException("index " + p + " is not between 0 and " + (n - 1));
40+
}
41+
}
42+
43+
private boolean connected(int p, int q) {
44+
return find(p) == find(q);
45+
}
46+
47+
private void union(int p, int q) {
48+
int rootP = find(p);
49+
int rootQ = find(q);
50+
if (rootP == rootQ) return;
51+
52+
// make smaller root point to larger one
53+
if (size[rootP] < size[rootQ]) {
54+
parent[rootP] = rootQ;
55+
size[rootQ] += size[rootP];
56+
} else {
57+
parent[rootQ] = rootP;
58+
size[rootP] += size[rootQ];
59+
}
60+
count--;
61+
}
62+
63+
private void link(int p, int q) {
64+
if (!connected(p, q)) {
65+
union(p, q);
66+
}
67+
}
68+
69+
public int numIslands(char[][] grid) {
70+
if (grid == null || grid.length == 0)
71+
return 0;
72+
int row = grid.length;
73+
int col = grid[0].length;
74+
75+
int n = row * col;
76+
int p = -1;
77+
int q = -1;
78+
79+
// take advantage of WeightedQuickUnionUF from Algs4
80+
// https://algs4.cs.princeton.edu/15uf/WeightedQuickUnionUF.java.html
81+
init(n);
82+
83+
int zeroCnt = 0;
84+
85+
for (int i = 0; i < row; i++) {
86+
for (int j = 0; j < col; j++) {
87+
int pos = i * col + j;
88+
89+
if (grid[i][j] == '1') {
90+
if (i + 1 < row) {
91+
if (grid[i + 1][j] == '1') {
92+
int p2 = (i + 1) * col + j;
93+
link(pos, p2);
94+
95+
System.out.println(String.format(">>> Evaluate pos [%d, %d]", pos, p2));
96+
}
97+
}
98+
if (j + 1 < col) {
99+
if (grid[i][j + 1] == '1') {
100+
int p2 = i * col + j + 1;
101+
link(pos, p2);
102+
103+
System.out.println(String.format(">>> Evaluate pos [%d, %d]", pos, p2));
104+
}
105+
}
106+
} else {
107+
++zeroCnt;
108+
}
109+
}
110+
}
111+
112+
return count() - zeroCnt;
113+
}
114+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package org.sean.array;
2+
3+
import org.junit.Assert;
4+
import org.junit.Before;
5+
import org.junit.Test;
6+
7+
import static org.junit.Assert.*;
8+
9+
public class IslandCounterTest {
10+
11+
private IslandCounter counter;
12+
13+
@Before
14+
public void setup() {
15+
counter = new IslandCounter();
16+
}
17+
18+
@Test
19+
public void numIslands() {
20+
int islands = counter.numIslands(new char[][]{
21+
{'1', '1', '0', '0', '0'},
22+
{'1', '1', '0', '0', '0'},
23+
{'0', '0', '1', '0', '0'},
24+
{'0', '0', '0', '1', '1'}
25+
});
26+
27+
Assert.assertEquals(3, islands);
28+
}
29+
}

0 commit comments

Comments
 (0)