当前位置:  首页>> 技术小册>> 数据结构与算法(中)

难度:
Hard

题意:

  1. 给定一张矩阵图
  2. 如果两个点相邻且都为1,这两个点连通
  3. 至多把一个0改为1,问最大的连通岛的面积是多大

思路:

  • 看数据结构,横竖最大是50,整个图最多才2500个点,直接枚举所有的0,改成1之后做dfs判断连通图,都可以解决
  • 两个连通岛其实是两个集合,如果将一个0改成1,意味着把上下左右所在的岛都合并在一个集合中,我们需要一个数据结构,既可以将集合合并,又可以判断某两个元素是否在同一个集合中,这种数据结构就是并查集

解法:

  1. class Solution {
  2. private class Set {
  3. int[] s;
  4. int[] num;
  5. int r;
  6. int c;
  7. private Set(int r, int c) {
  8. this.r = r;
  9. this.c = c;
  10. this.s = new int[r * c];
  11. this.num = new int[r * c];
  12. for (int i = 0;i < this.s.length;i++) {
  13. this.s[i] = i;
  14. this.num[i] = 1;
  15. }
  16. }
  17. private int calIdx(int x, int y) {
  18. return x * c + y;
  19. }
  20. private int find(int idx) {
  21. if (this.s[idx] == idx) {
  22. return idx;
  23. } else {
  24. return this.s[idx] = find(this.s[idx]);
  25. }
  26. }
  27. private void merge(int x1, int y1, int x2, int y2) {
  28. int p1 = find(calIdx(x1, y1));
  29. int p2 = find(calIdx(x2, y2));
  30. if (p1 != p2) {
  31. this.s[p1] = p2;
  32. this.num[p2] += this.num[p1];
  33. }
  34. }
  35. }
  36. public int largestIsland(int[][] grid) {
  37. int[] dx = new int[]{0,0,1,-1};
  38. int[] dy = new int[]{1,-1,0,0};
  39. Set set = new Set(grid.length, grid[0].length);
  40. for (int i = 0;i < grid.length;i++) {
  41. for (int j = 0;j < grid[0].length;j++) {
  42. if (grid[i][j] == 0) {
  43. continue;
  44. }
  45. for (int k = 0;k < 4;k++) {
  46. if (i + dx[k] < 0 || i + dx[k] >= grid.length) {
  47. continue;
  48. }
  49. if (j + dy[k] < 0 || j + dy[k] >= grid[0].length) {
  50. continue;
  51. }
  52. if (grid[i + dx[k]][j + dy[k]] == 0) {
  53. continue;
  54. }
  55. set.merge(i, j, i + dx[k], j + dy[k]);
  56. }
  57. }
  58. }
  59. int max = 0;
  60. for (int i = 0;i < grid.length;i++) {
  61. for (int j = 0; j < grid[0].length; j++) {
  62. if (grid[i][j] == 1) {
  63. continue;
  64. }
  65. HashSet<Integer> t = new HashSet<>();
  66. for (int k = 0;k < 4;k++) {
  67. if (i + dx[k] < 0 || i + dx[k] >= grid.length) {
  68. continue;
  69. }
  70. if (j + dy[k] < 0 || j + dy[k] >= grid[0].length) {
  71. continue;
  72. }
  73. if (grid[i + dx[k]][j + dy[k]] == 0) {
  74. continue;
  75. }
  76. t.add(set.find(set.calIdx(i + dx[k], j + dy[k])));
  77. }
  78. int ret = 0;
  79. for (Integer p: t) {
  80. ret += set.num[p];
  81. }
  82. ret ++;
  83. max = Math.max(ret, max);
  84. }
  85. }
  86. if (max == 0) {
  87. max = grid.length * grid[0].length;
  88. }
  89. return max;
  90. }
  91. }

该分类下的相关小册推荐: