岛屿数量(javascript实现)

321 阅读3分钟

岛屿数量 (力扣第200题,难度中等,深度优先)

先牢骚两句,个人简介挂了"热爱前端,也爱算法",但是一直没有写过算法题的文章,连我都怀疑自己是吹的,今天正好和同学视频交流学习,顺便边交流边写掘金,搞个算法集,把时间充分利用起来。

先看题目描述

给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。
岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。
此外,你可以假设该网格的四条边均被水包围。
实例:
输入:grid = [
  ["1","1","0","0","0"],
  ["1","1","0","0","0"],
  ["0","0","1","0","0"],
  ["0","0","0","1","1"]
]
输出:3
//说人话就是看二维矩阵中块的个数,块就是上下左右四个方向可以连接在一起的1形成的最大区域。
//     [1,1,0,0]
//比如 [1,1,0,1] 就有四个相连1和最后一个单独的1。就代表两个岛屿

建议先思考

乍一看岛屿题百分百广度优先,但是仔细一想又没有实现思路,我原本的想法是比较笨的,遍历整个二维数组,如果碰到是1的就进行广度优先遍历,并且把此次遍历到的所有元素的行和列都添加到一个对象中表示一个岛屿中包含的所有元素。之后继续遍历二维数组,如果元素在对象中已经存在了就不添加,否则就代表一个新的岛屿,继续存入到对象中(我习惯用对象来直接代替map)。可以,想的挺好的,但是一想时间复杂度。。。搞毛啊,一个元素最差就是O(n^2)了还玩个屁。

想了一阵子,同学提醒我岛屿题的主要思路就是将遍历过的元素置为新值,焯,突然顿悟了,是啊这样就可以避免掉查找元素是否已经被遍历的过程,然后啪啦啪啦一顿敲,花了十分钟,做出来了

var numIslands = function (grid) {
      let count = 0;
      function dfs(i, j) {
      //如果是0或者已经被遍历过,不继续遍历,直接返回
        if (grid[i][j] == -1 || grid[i][j] == 0) return;
        //将遍历到的元素置为-1,表示遍历过
        grid[i][j] = -1;
        //对上下左右四个方向进行遍历
        if (i + 1 < grid.length) {
          dfs(i + 1, j);
        }
        if (j + 1 < grid[0].length) {
          dfs(i, j + 1);
        }
        if (i - 1 >= 0) {
          dfs(i - 1, j);
        }
        if (j - 1 >= 0) {
          dfs(i, j - 1);
        }
      }

      //遍历二维数组,一旦有元素==1,开启广度优先遍历
      for (let i = 0; i < grid.length; i++) {
        for (let j = 0; j < grid[i].length; j++) {
          if (grid[i][j] == 1) {
            dfs(i, j);
            count++;
          }
        }
      }
      return count;
    };

如果有更好的想法可以在评论区交流,第一次写算法类文章,只是为了记录的同时加深印象,大佬轻喷。