给你一个大小为 n x n 二进制矩阵 grid 。最多 只能将一格 0 变成 1 。
返回执行此操作后,grid 中最大的岛屿面积是多少?
岛屿 由一组上、下、左、右四个方向相连的 1 形成。
输入: grid = [[1, 0], [0, 1]]
输出: 3
解释: 将一格0变成1,最终连通两个小岛得到面积为 3 的岛屿。
输入: grid = [[1, 1], [1, 0]]
输出: 4
解释: 将一格0变成1,岛屿的面积扩大为 4。
输入: grid = [[1, 1], [1, 1]]
输出: 4
解释: 没有0可以让我们变成1,面积依然为 4。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/making-a-large-island
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
⭐题解:https://leetcode.cn/problems/making-a-large-island/solution/by-muse-77-37hi/
1、将岛屿编号,并将(岛屿编号,岛屿面积)存入哈希表中。
2、判断非岛屿上下左右是否能连通。用set来防止重复加。
class Solution {
int[] directions = new int[]{-1, 0, 1, 0, -1};
int n;
public int largestIsland(int[][] grid) {
n = grid.length;
int res = 0, idx = 2; // 0 和 1都用了,所以从2开始编号
//将(索引,面积)存入map中。
//即求,编号后,每个岛屿的面积
Map<Integer, Integer> area = new HashMap<>();
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == 1) {
area.put(idx, caculateArea(idx, grid, i, j));
idx++;
}
}
}
//当遇到一个非岛屿时,则判断上下左右是否连通
//使用set去重,防止重复计算
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
int sum = 0;
Set<Integer> set = new HashSet<>(); //去重
if (grid[i][j] == 0) {
sum += 1;
//上
if (i - 1 >= 0 && grid[i - 1][j] != 0 && set.add(grid[i - 1][j])) {
sum += area.get(grid[i - 1][j]);
}
//下
if (i + 1 < n && grid[i + 1][j] != 0 && set.add(grid[i + 1][j])) {
sum += area.get(grid[i + 1][j]);
}
//左
if (j - 1 >= 0 && grid[i][j - 1] != 0 && set.add(grid[i][j - 1])) {
sum += area.get(grid[i][j - 1]);
}
//右
if (j + 1 < n && grid[i][j + 1] != 0 && set.add(grid[i][j + 1])) {
sum += area.get(grid[i][j + 1]);
}
}
res = Math.max(res, sum);
}
}
return res == 0 ? area.get(2) : res;
}
//BFS计算岛屿面积
//将连通岛屿格子值赋值为的岛屿编号
public int caculateArea(int idx, int[][] grid, int i, int j) {
Queue<int[]> q = new LinkedList<>();
q.offer(new int[]{i, j});
grid[i][j] = idx;
int sum = 0;
while (!q.isEmpty()) {
int[] cur = q.poll();
sum++;
for (int k = 0; k < directions.length - 1; k++) {
int x = cur[0] + directions[k];
int y = cur[1] + directions[k + 1];
if (x < 0 || x >= n || y < 0 || y >= n || grid[x][y] != 1) continue;
grid[x][y] = idx;
q.offer(new int[]{x, y});
}
}
return sum;
}
}