LeetCode热题(JS版)- 200. 岛屿数量

94 阅读1分钟

题目

给你一个由 '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'

思路:深度递归 + 四叉树搜索

function numIslands(grid: string[][]): number {
    let islands = 0;
    // 异常处理
    if(!grid || !grid.length || !grid[0] || !grid[0].length) return islands;

    // 标记位
    const m = grid.length;
    const n = grid[0].length;
    const visited = new Array(m).fill(false).map(d => {
        return new Array(n).fill(false);
    });

    // DFS
    const dfs = (i, j) => {
        // 终止条件:越界,遇到水,标记过
        if(i < 0 || i >= m || j < 0 || j >= n || visited[i][j] || grid[i][j] === '0') return;
        
        // 标记
        visited[i][j] = true;

        // 四叉树搜索
        dfs(i, j - 1)
        dfs(i, j + 1)
        dfs(i + 1, j)
        dfs(i - 1, j)
    }

    // 行列遍历
    for(let i = 0; i < m; i++) {
        for(let j = 0; j < n; j++) {
            // 新的岛屿
            if(!visited[i][j] && grid[i][j] === '1') {
                islands++;
                dfs(i, j);
            }
        }
    }

    return islands;
};

image.png

总结

  • 时间复杂度:O(mn),其中 m 和 n 分别是二维网格地图的行数和列数。最坏情况下,我们需要遍历整个二维网格地图才能计算岛屿数量。
  • 空间复杂度:O(mn),其中 m 和 n 分别是二维网格地图的行数和列数。在最坏情况下,整个二维网格地图均为陆地,此时递归深度达到 mn,标记数组 visited 占用 O(mn) 的额外空间。
  • 本题是一道比较典型的深度优先搜索(DFS)或广度优先搜索(BFS)的应用题,我们可以采用 DFS 或 BFS 的方式来解决这个问题。时间复杂度为 O(mn),空间复杂度为 O(mn)。