给你一个大小为 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]
为0
或1
解题
/**
* @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;
};