最大人工岛

58 阅读1分钟

827. 最大人工岛 - 力扣(LeetCode)

给你一个大小为 n x n 二进制矩阵 grid最多 只能将一格 0 变成 1

返回执行此操作后,grid 中最大的岛屿面积是多少?

岛屿 由一组上、下、左、右四个方向相连的 1 形成。

示例 1:

输入: grid = [[1, 0], [0, 1]]
输出: 3
解释: 将一格0变成1,最终连通两个小岛得到面积为 3 的岛屿。

示例 2:

输入: grid = [[1, 1], [1, 0]]
输出: 4
解释: 将一格0变成1,岛屿的面积扩大为 4。

示例 3:

输入: grid = [[1, 1], [1, 1]]
输出: 4
解释: 没有0可以让我们变成1,面积依然为 4。

提示:

  • n == grid.length
  • n == grid[i].length
  • 1 <= n <= 500
  • grid[i][j]01

解题

/**
 * @param {number[][]} grid
 * @return {number}
 */
var largestIsland = function (grid) {
  const n = grid.length;
  const validCell = (r, c) => {
    return r >= 0 && r < n && c >= 0 && c < n;
  };
  let area;
  let res = 1;
  let areaMap = new Array(n).fill(0).map(() => new Array(n));
  let steps = [
    [0, 1],
    [1, 0],
    [0, -1],
    [-1, 0],
  ];
  const getLand = (r, c) => {
    areaMap[r][c] = area;
    area.value += 1;
    grid[r][c] = -1;
    for (let i = 0; i < 4; i++) {
      const nr = r + steps[i][0];
      const nc = c + steps[i][1];
      if (validCell(nr, nc) && grid[nr][nc] === 1) {
        getLand(nr, nc);
      }
    }
  };
  for (let r = 0; r < n; r++) {
    for (let c = 0; c < n; c++) {
      if (grid[r][c] === 1) {
        area = { value: 0 };
        getLand(r, c);
        res = Math.max(res, area.value);
      }
    }
  }
  if (res === n * n) return res;
  const getJoinLand = (r, c) => {
    let areas = new Set();
    if (validCell(r, c) && grid[r][c] === 0) {
      for (let i = 0; i < 4; i++) {
        const nr = r + steps[i][0];
        const nc = c + steps[i][1];
        if (validCell(nr, nc) && grid[nr][nc] === -1) {
          areas.add(areaMap[nr][nc]);
        }
      }
    }
    return areas;
  };
  for (let r = 0; r < n; r++) {
    for (let c = 0; c < n; c++) {
      if (grid[r][c] === -1) {
        area = areaMap[r][c];
        for (let i = 0; i < 2; i++) {
          let count = area.value + 1;
          const areas = getJoinLand(r + steps[i][0], c + steps[i][1]);
          areas.delete(area);
          for (let item of areas) {
            count += item.value;
          }
          res = Math.max(res, count);
        }
      }
    }
  }
  return res;
};