编码母题 / P1 / 经典算法 / 08

岛屿数量与最大岛屿面积

重要程度必练难度中等预计完成30–40 分钟

题目是什么

输入只含数字 0 和 1 的矩形二维数组 grid;上下左右相邻的 1 连成一座岛,对角相邻不连通。返回 { count, maxArea },面积为岛内 1 的个数;空网格返回两个 0,且不得修改输入。

输入输出示例

[[1,1,0],[0,1,0],[1,0,1]] 含 3 座岛,最大岛面积 3,返回 { count: 3, maxArea: 3 }。

练习起手式与验证

/*
 * 题目:岛屿数量与最大岛屿面积
 * 要求:输入只含数字 0 和 1 的矩形二维数组 grid;上下左右相邻的 1 连成一座岛,对角相邻不连通。返回 { count, maxArea },面积为岛内 1 的个数;空网格返回两个 0,且不得修改输入。
 * 示例:[[1,1,0],[0,1,0],[1,0,1]] 含 3 座岛,最大岛面积 3,返回 { count: 3, maxArea: 3 }。
 */
function analyzeIslands(grid) {}
console.log(analyzeIslands([[1, 1, 0], [0, 1, 0], [1, 0, 1]])); // 预期:{ count: 3, maxArea: 3 }
console.log(analyzeIslands([])); // 预期:{ count: 0, maxArea: 0 }
console.log(analyzeIslands([[0, 0], [0, 0]])); // 预期:{ count: 0, maxArea: 0 }
console.log(analyzeIslands([[1, 1], [1, 1]])); // 预期:{ count: 1, maxArea: 4 }

解题思路与实现

展开解题思路

每遇到未访问陆地就启动一次迭代搜索;一次搜索恰好覆盖一个连通分量。

function analyzeIslands(grid) {
  if (!Array.isArray(grid) || !grid.length) return { count: 0, maxArea: 0 };
  const columns = grid[0].length;
  if (!grid.every((row) => Array.isArray(row) && row.length === columns))
    throw new TypeError("grid must be rectangular");
  const visited = Array.from({ length: grid.length }, () =>
    Array(columns).fill(false),
  );
  const directions = [
    [1, 0],
    [-1, 0],
    [0, 1],
    [0, -1],
  ];
  let count = 0;
  let maxArea = 0;
  for (let r = 0; r < grid.length; r += 1)
    for (let c = 0; c < columns; c += 1) {
      if (!grid[r][c] || visited[r][c]) continue;
      count += 1;
      let area = 0;
      const stack = [[r, c]];
      visited[r][c] = true;
      while (stack.length) {
        const [row, column] = stack.pop();
        area += 1;
        for (const [dr, dc] of directions) {
          const nr = row + dr;
          const nc = column + dc;
          if (
            nr >= 0 &&
            nr < grid.length &&
            nc >= 0 &&
            nc < columns &&
            grid[nr][nc] &&
            !visited[nr][nc]
          ) {
            visited[nr][nc] = true;
            stack.push([nr, nc]);
          }
        }
      }
      maxArea = Math.max(maxArea, area);
    }
  return { count, maxArea };
}

// 三组以上可直接运行的验证。
console.log(analyzeIslands([[1, 1, 0], [0, 1, 0], [1, 0, 1]])); // 预期:{ count: 3, maxArea: 3 }
console.log(analyzeIslands([])); // 预期:{ count: 0, maxArea: 0 }
console.log(analyzeIslands([[0, 0], [0, 0]])); // 预期:{ count: 0, maxArea: 0 }
console.log(analyzeIslands([[1, 1], [1, 1]])); // 预期:{ count: 1, maxArea: 4 }

时间复杂度:O(R·C)。每个网格单元最多入栈和检查有限次。

空间复杂度:O(R·C)。访问标记及最坏情况下的搜索栈覆盖整个网格。

下载原始 JS 文件