forked from fishercoder1534/Leetcode
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathNumberOfIslandsUnionFind.java
81 lines (70 loc) · 2.19 KB
/
NumberOfIslandsUnionFind.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
package com.stevesun.solutions;
/**
* Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.
Example 1:
11110
11010
11000
00000
Answer: 1
Example 2:
11000
11000
00100
00011
Answer: 3
*/
public class NumberOfIslandsUnionFind {
class UnionFind{
int count;
int m, n;
int[] ids;
public UnionFind(char[][] grid){
m = grid.length;
n = grid[0].length;
ids = new int[m*n];
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
if(grid[i][j] == '1') {
count++;
ids[i*n+j] = i*n+j;
}
}
}
}
public void union(int i, int j){
int x = find(ids, i);
int y = find(ids, j);
if(x != y) {//note: this is when x != y, only in this case, we should union these two nodes, which makes sense naturally.
count--;
ids[x] = y;
}
}
public int find(int[] ids, int i){
if(ids[i] == i) return i;
return find(ids, ids[i]);
}
}
public int numIslands(char[][] grid) {
if(grid == null || grid.length == 0 || grid[0].length == 0) return 0;
int[] dirs = new int[]{0,1,0,-1,0};
UnionFind uf = new UnionFind(grid);
int m = grid.length, n = grid[0].length;
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
if(grid[i][j] == '1'){
for(int k = 0; k < 4; k++){
int x = i+dirs[k];
int y = j+dirs[k+1];
if(x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == '1'){
int id1 = i*n+j;
int id2 = x*n+y;
uf.union(id1, id2);
}
}
}
}
}
return uf.count;
}
}