一,题目

二,分析

三,解法

四,参考

leetcode网站的题解参考

Union Find的一种别样实现(解释rank)

  1. class Solution {
  2. public int[] hitBricks(int[][] grid, int[][] hits) {
  3. int R = grid.length, C = grid[0].length;
  4. int[] dr = {1, 0, -1, 0};
  5. int[] dc = {0, 1, 0, -1};
  6. int[][] A = new int[R][C];
  7. for (int r = 0; r < R; ++r)
  8. A[r] = grid[r].clone();
  9. for (int[] hit: hits)
  10. A[hit[0]][hit[1]] = 0;
  11. DSU dsu = new DSU(R*C + 1);
  12. for (int r = 0; r < R; ++r) {
  13. for (int c = 0; c < C; ++c) {
  14. if (A[r][c] == 1) {
  15. int i = r * C + c;
  16. if (r == 0)
  17. dsu.union(i, R*C);
  18. if (r > 0 && A[r-1][c] == 1)
  19. dsu.union(i, (r-1) *C + c);
  20. if (c > 0 && A[r][c-1] == 1)
  21. dsu.union(i, r * C + c-1);
  22. }
  23. }
  24. }
  25. int t = hits.length;
  26. int[] ans = new int[t--];
  27. while (t >= 0) {
  28. int r = hits[t][0];
  29. int c = hits[t][1];
  30. int preRoof = dsu.top();
  31. if (grid[r][c] == 0) {
  32. t--;
  33. } else {
  34. int i = r * C + c;
  35. for (int k = 0; k < 4; ++k) {
  36. int nr = r + dr[k];
  37. int nc = c + dc[k];
  38. if (0 <= nr && nr < R && 0 <= nc && nc < C && A[nr][nc] == 1)
  39. dsu.union(i, nr * C + nc);
  40. }
  41. if (r == 0)
  42. dsu.union(i, R*C);
  43. A[r][c] = 1;
  44. ans[t--] = Math.max(0, dsu.top() - preRoof - 1);
  45. }
  46. }
  47. return ans;
  48. }
  49. }
  50. class DSU {
  51. int[] parent;
  52. int[] rank;
  53. int[] sz;
  54. public DSU(int N) {
  55. parent = new int[N];
  56. for (int i = 0; i < N; ++i)
  57. parent[i] = i;
  58. rank = new int[N];
  59. sz = new int[N];
  60. Arrays.fill(sz, 1);
  61. }
  62. //这里采用了路径压缩,在搜索的时候把所有经过的节点的parent都指向了根节点
  63. public int find(int x) {
  64. if (parent[x] != x) parent[x] = find(parent[x]);
  65. return parent[x];
  66. }
  67. public void union(int x, int y) {
  68. int xr = find(x), yr = find(y);
  69. if (xr == yr) return;
  70. //这里的交换操作使得yr永远是是权重(rank)小的那个
  71. if (rank[xr] < rank[yr]) {
  72. int tmp = yr;
  73. yr = xr;
  74. xr = tmp;
  75. }
  76. if (rank[xr] == rank[yr])
  77. rank[xr]++;
  78. //yr是权重(rank)小的那个
  79. parent[yr] = xr;
  80. sz[xr] += sz[yr];
  81. }
  82. public int size(int x) {
  83. return sz[find(x)];
  84. }
  85. public int top() {
  86. return size(sz.length - 1) - 1;
  87. }
  88. }