当前位置:   article > 正文

LeetCode Java 深度优先算法(DFS)实现岛屿个数计算,附带详细分析_dfs算法之leetcode实战ja va

dfs算法之leetcode实战ja va


理解:首先要看懂题目,这道题什么意思,还有这输入的一连串数字什么意思。说实话刚开始没看懂,我以为是中间包含周围 4 个格子,岛屿的为 1,海域为 0。实在没看懂的我去翻了百度上大佬写的算法看懂了,然后自己写了一遍,并发逻辑分析一步一步的写下来,方便大伙学习。话说这个数字是这意思。。。

  
靠,居然是图形化,简直侮辱我智商,我在那分析了半天这数字啥意思。。。

分析:我们通过循环找到岛屿的根节点后,借由深度优先算法的思想,从岛屿的一个分支一直探索这个分支的尽头,再从另一个分支去探索,以此类推。比如这里的按照 上,下,左,右 的顺序,依次向深处探索,上面没路向下走,下面没路就向左,左边没有就向右,右边也没路,说明这个分支全探索完,探索下一个分支的路径。
PS:不走回头路

怎么说有点像玩情景对话游戏,先全部选第一个选项,到游戏结束,再从上一个分支点读档,玩完后再度档,以此类推就可以把所有的剧情都玩一遍

实现:接下来就是具体的实现,对于代码层面上的分析,我都详细的写在注释上了

  1. /**
  2. * DFS 深度优先算法实现岛屿个数探索
  3. * @author: author
  4. * @create: 2019-07-30 15:59
  5. **/
  6. public class IsLandDfs {
  7. /**
  8. * 判断是否是岛屿,然后统计岛屿数量
  9. * @param isLand 未知海域数组
  10. * @return 返回岛屿数量
  11. */
  12. public static Integer isLand(int[][] isLand) {
  13. // 都没东西玩啥
  14. if (isLand.length == 0) {
  15. return 0;
  16. }
  17. // 岛屿数量
  18. int count = 0;
  19. // 记录已经探索过的岛屿,其中里面的值,0 表示未探索,1 表示已探索
  20. int[][] isVisit = new int[isLand.length][isLand[0].length];
  21. // 循环未知海域的二维数组
  22. for (int i = 0; i < isLand.length; i ++) {
  23. for (int j = 0; j < isLand[i].length; j ++) {
  24. // isVisit 为 0 表示海域未探索岛屿
  25. // 这个判断的目的在于
  26. // 如果这个区域已经探索过了,这个岛屿与之前的岛屿相连,不增加岛屿数量
  27. // 如果这个是个新岛屿,那么岛屿周围肯定都是海水,岛屿探索是无法探索到这的
  28. // 不理解的可以把整个逻辑读懂后,思考下
  29. if (isVisit[i][j] == 0) {
  30. // isLand 为 1 表示这个是岛屿(根节点),你也可以看作最初的登陆点
  31. if (isLand[i][j] == 1) {
  32. count ++;
  33. System.out.println("岛屿登陆点(根节点),这是发现的第" + count + "座岛屿");
  34. }
  35. }
  36. // 开始 DFS 深度优先算法探索岛屿
  37. visitLand(isLand, isVisit, i, j);
  38. }
  39. }
  40. return count;
  41. }
  42. /**
  43. * DFS 深度优先算法岛屿探索,从岛屿的根节点开始
  44. * 把与这个岛屿相连的岛屿全部在 isVisit 中做上标记
  45. * @param isLand
  46. * @param isVisit
  47. * @param i
  48. * @param j
  49. */
  50. public static void visitLand(int[][] isLand, int[][] isVisit, int i, int j) {
  51. // 判断越界
  52. // 为何哟判断越界,有些人可能不太明白,i 和 j 都是从 0 开始的,怎么可能小于 0 呢?
  53. // 因为下面需要对所有相邻的区域去探索就会出现越界的情况
  54. // 比如 i = 0, j = 0 点为岛屿,我要向左探索,这时候 i - 1 = -1,这时就会出现越界的情况
  55. // 这让我不禁想起玩 RPG 游戏的时候,有时候走到地图外边就报错了,估计就是跨域没判断好
  56. if (i < 0 || j < 0 || i >= isLand.length || j >= isLand[i].length) {
  57. return;
  58. }
  59. // 遇到海洋了,不是岛屿不探索
  60. if (isLand[i][j] == 0) {
  61. return;
  62. }
  63. // 已经探索过的与岛屿相连的地方
  64. // 什么意思?就是你是从那里探索过来的,不需要再探索回去了
  65. if (isVisit[i][j] == 1) {
  66. return;
  67. }
  68. // 记录下这个点探索过了
  69. isVisit[i][j] = 1;
  70. // 开始探索陆地
  71. // 这里注意:i 是循环行, j 是循环列
  72. // 比如: i = 2,i - 1 就是从第 2 行向第 1 行去探索,是向上
  73. // 不理解的可以好好捋一捋
  74. // 向岛屿上面探索
  75. visitLand(isLand, isVisit, i - 1, j);
  76. // 向岛屿下面探索
  77. visitLand(isLand, isVisit, i + 1, j);
  78. // 向岛屿左边探索
  79. visitLand(isLand, isVisit, i, j - 1);
  80. // 向岛屿右边探索
  81. visitLand(isLand, isVisit, i, j + 1);
  82. }
  83. public static void main(String[] args) {
  84. // 岛屿 二维数组(图形化)
  85. int [][] isLand = {{1, 1, 0, 0, 0},{1, 1, 0, 0, 0},{0, 0, 1, 0, 0},{0, 0, 0, 1, 1}};
  86. int count = isLand(isLand);
  87. System.out.println("一共探索到" + count + "座岛屿");
  88. }
  89. }

附带广度优先算法的实现:
Java 队列结合广度优先算法(BFS)实现岛屿个数计算,附带详细分析

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/476037
推荐阅读
相关标签
  

闽ICP备14008679号