[前端]_一起刷leetcode 200. 岛屿数量

132 阅读3分钟

大家好,我是挨打的阿木木,爱好算法的前端摸鱼老。最近会频繁给大家分享我刷算法题过程中的思路和心得。如果你也是想提高逼格的摸鱼老,欢迎关注我,一起学习。

题目

200. 岛屿数量

给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。

岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。

此外,你可以假设该网格的四条边均被水包围。

 

示例 1:

输入: grid = [  ["1","1","1","1","0"],
  ["1","1","0","1","0"],
  ["1","1","0","0","0"],
  ["0","0","0","0","0"]
]
输出: 1

示例 2:

输入: grid = [  ["1","1","0","0","0"],
  ["1","1","0","0","0"],
  ["0","0","1","0","0"],
  ["0","0","0","1","1"]
]
输出: 3

 

提示:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 300
  • grid[i][j] 的值为 '0' 或 '1'

思路

  1. 两层for循环,去遍历我们矩阵中的每一个元素,如果遍历到的节点值为"1",那么进行消除;
  2. 消除规则是这样子的,像我们玩扫雷一样,中间一个是1了那把跟它紧挨着的几个元素全都改成0
  3. 但是这道题目我们要进行连续的消除,所以我们要对下一个元素做同样的操作,也就形成了递归问题;
  4. 那么递归的条件是什么呢?就是直到超出边界或者当前元素本身就是0这两种情况;
  5. 所以我们只需要在递归时判断是否达到了这两种情况,如果是就不往下执行,如果不是就消除它四周的元素。

dfs + 递归

/**
 * @param {character[][]} grid
 * @return {number}
 */
var numIslands = function(grid) {
    const m = grid.length, n = grid[0].length;

    // 快乐消除
    function dfs(grid, i, j) { 
        // 判断是否超出边界
        if (i < 0 || j < 0 || i >= m || j >= n || grid[i][j] === "0") {
            return;
        }

        grid[i][j] = "0";
        
        // 朝四周扩散
        dfs(grid, i - 1, j);
        dfs(grid, i + 1, j);
        dfs(grid, i, j - 1);
        dfs(grid, i, j + 1);
    }
   

    let result = 0;

    for (let i = 0; i < m; i++) {
        for (let j = 0; j < n; j++) {
            if (grid[i][j] === "1") {
                dfs(grid, i, j);
                result++;
            }
        }
    }

    return result;
};

bfs + 迭代

迭代的思路跟递归基本一直,只不过是把四周的元素全部放到待操作的数组里面,一个一个拿出来,这样子其实每一轮只需要存储一行或者一列元素即可,可以省下一定的空间。当然,如果这道题目要优化,可以把判断操作放到push的代码之前,如果溢出边界则不push,这样子可以达到最高性能,不过我为了方便理解就用最精简的代码来实现。

/**
 * @param {character[][]} grid
 * @return {number}
 */
var numIslands = function(grid) {
    const m = grid.length, n = grid[0].length;

    // 快乐消除
    function bfs(grid, queue) { 
        while (queue.length) {
          let { i, j } = queue.shift();
          // 判断是否超出边界
          if (!(i < 0 || j < 0 || i >= m || j >= n || grid[i][j] === "0")) {
              grid[i][j] = "0";

              queue.push({ i: i - 1, j });
              queue.push({ i: i + 1, j });
              queue.push({ i, j: j - 1 });
              queue.push({ i, j: j + 1 });
          }

        }
    }

    let result = 0;

    for (let i = 0; i < m; i++) {
        for (let j = 0; j < n; j++) {
            if (grid[i][j] === "1") {
                bfs(grid, [{ i, j }]);
                result++;
            }
        }
    }

    return result;
};

看懂了的小伙伴可以点个关注、咱们下道题目见。如无意外以后文章都会以这种形式,有好的建议欢迎评论区留言。