LeetCode 算法:岛屿数量

73 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第 12 天,点击查看活动详情

岛屿数量

原题地址

给你一个由 '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. 按照题目分析,需要计算岛屿的数量,那么需要判断每个方格周边是陆地还是海水,因为题目中的岛屿总是由海水包围;
  2. 我们定义一个 result 来存储岛屿的数量,深度优先双层遍历数组中每个坐标的四周,若遇到陆地则将 result++,并且将四周的陆地变为海水,这样可以确保不会重复计算;
  3. 按照步骤2中的思路,来遍历数组,并且定义 setSea 方法,将四周的陆地变为海水;
  4. setSea 中的逻辑也比较简单,主要执行实现的是将陆地四周都变成海水,也就是将坐标 [i, j] 四周的坐标 [i, j+1][i, j-1][i+1, j][i-1, j] 都置为 '0',若下标越界或者本身就是海水,那么久不需要做重复的操作了;
  5. 经过上述步骤的操作,最终将 result 返回即可。

AC 代码

/**
 * @param {character[][]} grid
 * @return {number}
 */
var numIslands = function(grid) {
    let result = 0
    for (let i = 0; i < grid.length; i++) {
        for (let j = 0; j < grid[0].length; j++) {
            if (grid[i][j] === '1') {
                result++
                setSea(i, j, grid)
            }
        }
    }
    return result
};

function setSea(i, j, grid) {
    if (i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] === '0') return 
    grid[i][j] = '0'
    setSea(i, j + 1, grid)
    setSea(i, j - 1, grid)
    setSea(i + 1, j, grid)
    setSea(i - 1, j, grid)
}

结果:

  • 执行结果: 通过
  • 执行用时:76 ms, 在所有 JavaScript 提交中击败了71.00%的用户
  • 内存消耗:43.7 MB, 在所有 JavaScript 提交中击败了67.21%的用户
  • 通过测试用例:49 / 49

END