【算法】 岛屿的最大面积

136 阅读2分钟

难度:中等

题目

给你一个大小为 m x n 的二进制矩阵 grid

岛屿 是由一些相邻的 1 (代表土地) 构成的组合,这里的「相邻」要求两个 1 必须在 水平或者竖直的四个方向上 相邻。你可以假设 grid 的四个边缘都被 0(代表水)包围着。

岛屿的面积是岛上值为 1 的单元格的数目。

计算并返回 grid 中最大的岛屿面积。如果没有岛屿,则返回面积为 0

示例:

示例1:

输入:

grid = [  [0,0,1,0,0,0,0,1,0,0,0,0,0],
  [0,0,0,0,0,0,0,1,1,1,0,0,0],
  [0,1,1,0,1,0,0,0,0,0,0,0,0],
  [0,1,0,0,1,1,0,0,1,0,1,0,0],
  [0,1,0,0,1,1,0,0,1,1,1,0,0],
  [0,0,0,0,0,0,0,0,0,0,1,0,0],
  [0,0,0,0,0,0,0,1,1,1,0,0,0],
  [0,0,0,0,0,0,0,1,1,0,0,0,0]
]

输出:6

提示:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 50
  • grid[i][j]01

解题思路:

这个问题可以通过深度优先搜索(DFS)一次性遍历整个网格,避免重复计算和不必要的搜索。

  1. 初始化:创建一个变量 maxArea 用于存储最大岛屿的面积,初始化为 0。
  2. 遍历网格:使用两层嵌套循环遍历整个网格的每一个单元格。
  3. 深度优先搜索(DFS)
  • 对于每一个值为 1 的单元格,调用 DFS 函数来探索与之相邻的所有陆地单元格(上下左右)。
  • 在 DFS 函数中,每当遇到一个未访问过的陆地单元格时,将其标记为已访问,并递增岛屿面积计数器。
  • 当所有相邻的陆地单元格都被访问过后,更新 maxArea 为当前岛屿面积和 maxArea 中的较大值。
  1. 返回结果:遍历完成后,maxArea 将保存最大岛屿的面积,返回 maxArea

JavaScript实现:

function maxAreaOfIsland(grid) {
    let maxArea = 0;

    function dfs(r, c) {
        if (r < 0 || r >= grid.length || c < 0 || c >= grid[0].length || grid[r][c] === 0) {
            return 0;
        }
        grid[r][c] = 0; // 标记为已访问
        return (1 +
            dfs(r - 1, c) + // 上方
            dfs(r + 1, c) + // 下方
            dfs(r, c - 1) + // 左侧
            dfs(r, c + 1)); // 右侧
    }

    for (let r = 0; r < grid.length; r++) {
        for (let c = 0; c < grid[0].length; c++) {
            if (grid[r][c] === 1) {
                maxArea = Math.max(maxArea, dfs(r, c));
            }
        }
    }

    return maxArea;
}

时间复杂度:O(M*N),其中 M 和 N 分别是网格的行数和列数。每个单元格只会被访问一次。

空间复杂度:O(M

N),在最坏情况下,整个网格都是陆地,递归调用栈的深度可能达到 M

N。但实际上,由于递归深度受限于岛屿的实际大小,平均情况下空间复杂度远小于 O(M*N)。