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
| class Solution { private static class UnionFind { private final int[] parent;
public UnionFind(int n) { this.parent = new int[n]; for (int i = 0; i < parent.length; i++) { parent[i] = i; } }
public void union(int x, int y) { int xRoot = getRoot(x), yRoot = getRoot(y); if (xRoot == yRoot) { return; }
parent[xRoot] = yRoot; }
private int getRoot(int x) { if (parent[x] != x) { parent[x] = getRoot(parent[x]); } return parent[x]; }
}
private static final int[][] DIRECTIONS = new int[][]{{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
public int countSubIslands(int[][] grid1, int[][] grid2) { int m = grid1.length, n = grid1[0].length;
UnionFind unionFind = new UnionFind(m * n); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (grid1[i][j] == 1) { dfs(grid1, unionFind, i, j); } } }
int count = 0;
for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (grid2[i][j] == 1) { int root = unionFind.getRoot(toIndex(n, i, j)); if (dfsCheck(grid1, grid2, unionFind, root, i, j)) { count++; } } } }
return count; }
private boolean dfsCheck(int[][] grid1, int[][] grid2, UnionFind unionFind, int root, int i, int j) { int m = grid2.length, n = grid2[0].length;
boolean result = grid1[i][j] == 2; grid2[i][j] = 2;
for (int[] direction : DIRECTIONS) { int nextI = i + direction[0], nextJ = j + direction[1]; if (nextI >= 0 && nextI < m && nextJ >= 0 && nextJ < n && grid2[nextI][nextJ] == 1) { if (grid1[nextI][nextJ] != 2 || unionFind.getRoot(toIndex(n, nextI, nextJ)) != root) { result = false; } result &= dfsCheck(grid1, grid2, unionFind, root, nextI, nextJ); } }
return result; }
private void dfs(int[][] grid1, UnionFind unionFind, int i, int j) { int m = grid1.length, n = grid1[0].length;
grid1[i][j] = 2;
for (int[] direction : DIRECTIONS) { int nextI = i + direction[0], nextJ = j + direction[1]; if (nextI >= 0 && nextI < m && nextJ >= 0 && nextJ < n && grid1[nextI][nextJ] == 1) { unionFind.union(toIndex(n, i, j), toIndex(n, nextI, nextJ)); dfs(grid1, unionFind, nextI, nextJ); } } }
private int toIndex(int n, int i, int j) { return i * n + j; } }
|