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
| class Solution { public List<Integer> numIslands2(int m, int n, int[][] positions) { List<Integer> ans = new ArrayList<>();
int[][] dirs = new int[][]{{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
UnionFind uf = new UnionFind(m * n);
boolean[] visited = new boolean[m * n];
for (int[] pos : positions) { int x = pos[0]; int y = pos[1];
int idx = x * n + y;
if (visited[idx]) { ans.add(uf.getCount()); continue; }
uf.setParent(idx); visited[idx] = true;
for (int[] dir : dirs) { int nextX = x + dir[0]; int nextY = y + dir[1];
int nextIdx = nextX * n + nextY;
if (inArea(m, n, nextX, nextY) && uf.isValid(nextIdx) && visited[nextIdx]) { uf.union(idx, nextIdx); } }
ans.add(uf.getCount()); }
return ans; }
private static boolean inArea(int rows, int cols, int x, int y) { return x >= 0 && x < rows && y >= 0 && y < cols; }
class UnionFind { int[] parents; int[] rank; int count = 0;
UnionFind(int n) { parents = new int[n]; rank = new int[n]; count = 0;
Arrays.fill(parents, -1); }
boolean isValid(int x) { return parents[x] != -1; }
void setParent(int x) { if (parents[x] != x) { count++; }
parents[x] = x; }
int find(int x) { while (x != parents[x]) { parents[x] = parents[parents[x]]; x = parents[x]; }
return x; }
boolean isConnected(int x, int y) { return find(x) == find(y); }
void union(int x, int y) { int rootX = find(x); int rootY = find(y);
if (rootX == rootY) { return; }
if (rank[rootX] > rank[rootY]) { parents[rootY] = rootX; } else if (rank[rootX] < rank[rootY]) { parents[rootX] = rootY; } else { parents[rootY] = rootX; rank[rootX]++; }
count--; }
int getCount() { return count; } } }
|