class Solution:
def largestIsland(self, grid):
n = len(grid)
island_id = 2
area = {}
def dfs(r, c, id):
if r < 0 or r >= n or c < 0 or c >= n or grid[r][c] != 1:
return 0
grid[r][c] = id
res = 1
for dr, dc in [(-1,0),(1,0),(0,-1),(0,1)]:
res += dfs(r+dr, c+dc, id)
return res
# 1. Label each island with a unique id and compute its area
for r in range(n):
for c in range(n):
if grid[r][c] == 1:
area[island_id] = dfs(r, c, island_id)
island_id += 1
res = max(area.values() or [0])
# 2. Try to flip each 0 and sum the areas of neighboring islands
for r in range(n):
for c in range(n):
if grid[r][c] == 0:
seen = set()
for dr, dc in [(-1,0),(1,0),(0,-1),(0,1)]:
nr, nc = r+dr, c+dc
if 0 <= nr < n and 0 <= nc < n and grid[nr][nc] > 1:
seen.add(grid[nr][nc])
res = max(res, 1 + sum(area[i] for i in seen))
return res
class Solution {
public:
int n;
vector<vector<int>> dirs{{0,1},{0,-1},{1,0},{-1,0}};
int dfs(vector<vector<int>>& grid, int r, int c, int id) {
if (r < 0 || r >= n || c < 0 || c >= n || grid[r][c] != 1) return 0;
grid[r][c] = id;
int res = 1;
for (auto& d : dirs) {
res += dfs(grid, r + d[0], c + d[1], id);
}
return res;
}
int largestIsland(vector<vector<int>>& grid) {
n = grid.size();
unordered_map<int, int> area;
int island_id = 2;
// 1. Label each island and calculate area
for (int r = 0; r < n; ++r) {
for (int c = 0; c < n; ++c) {
if (grid[r][c] == 1) {
area[island_id] = dfs(grid, r, c, island_id);
++island_id;
}
}
}
int res = 0;
for (auto& kv : area) res = max(res, kv.second);
// 2. Try to flip each 0 and sum areas of neighboring islands
for (int r = 0; r < n; ++r) {
for (int c = 0; c < n; ++c) {
if (grid[r][c] == 0) {
unordered_set<int> seen;
int total = 1;
for (auto& d : dirs) {
int nr = r + d[0], nc = c + d[1];
if (nr >= 0 && nr < n && nc >= 0 && nc < n && grid[nr][nc] > 1) {
seen.insert(grid[nr][nc]);
}
}
for (int id : seen) total += area[id];
res = max(res, total);
}
}
}
return n * n == res ? res : max(res, 1); // handle all 0 grid
}
};
class Solution {
int n;
int[][] dirs = {{0,1},{1,0},{0,-1},{-1,0}};
int dfs(int[][] grid, int r, int c, int id) {
if (r < 0 || r >= n || c < 0 || c >= n || grid[r][c] != 1) return 0;
grid[r][c] = id;
int res = 1;
for (int[] d : dirs) {
res += dfs(grid, r + d[0], c + d[1], id);
}
return res;
}
public int largestIsland(int[][] grid) {
n = grid.length;
Map<Integer, Integer> area = new HashMap<>();
int island_id = 2;
// 1. Label each island and calculate area
for (int r = 0; r < n; ++r) {
for (int c = 0; c < n; ++c) {
if (grid[r][c] == 1) {
area.put(island_id, dfs(grid, r, c, island_id));
++island_id;
}
}
}
int res = 0;
for (int v : area.values()) res = Math.max(res, v);
// 2. Try to flip each 0 and sum areas of neighboring islands
for (int r = 0; r < n; ++r) {
for (int c = 0; c < n; ++c) {
if (grid[r][c] == 0) {
Set<Integer> seen = new HashSet<>();
int total = 1;
for (int[] d : dirs) {
int nr = r + d[0], nc = c + d[1];
if (nr >= 0 && nr < n && nc >= 0 && nc < n && grid[nr][nc] > 1) {
seen.add(grid[nr][nc]);
}
}
for (int id : seen) total += area.get(id);
res = Math.max(res, total);
}
}
}
return n*n == res ? res : Math.max(res, 1);
}
}
var largestIsland = function(grid) {
const n = grid.length;
let islandId = 2;
const area = {};
function dfs(r, c, id) {
if (r < 0 || r >= n || c < 0 || c >= n || grid[r][c] !== 1) return 0;
grid[r][c] = id;
let res = 1;
const dirs = [[-1,0],[1,0],[0,-1],[0,1]];
for (const [dr, dc] of dirs) {
res += dfs(r+dr, c+dc, id);
}
return res;
}
// 1. Label each island and calculate area
for (let r = 0; r < n; ++r) {
for (let c = 0; c < n; ++c) {
if (grid[r][c] === 1) {
area[islandId] = dfs(r, c, islandId);
++islandId;
}
}
}
let res = 0;
for (let key in area) res = Math.max(res, area[key]);
// 2. Try to flip each 0 and sum areas of neighboring islands
for (let r = 0; r < n; ++r) {
for (let c = 0; c < n; ++c) {
if (grid[r][c] === 0) {
const seen = new Set();
let total = 1;
const dirs = [[-1,0],[1,0],[0,-1],[0,1]];
for (const [dr, dc] of dirs) {
const nr = r + dr, nc = c + dc;
if (nr >= 0 && nr < n && nc >= 0 && nc < n && grid[nr][nc] > 1) {
seen.add(grid[nr][nc]);
}
}
for (let id of seen) total += area[id];
res = Math.max(res, total);
}
}
}
return res === 0 ? 1 : res;
};
You are given an n x n
binary grid, where each cell contains either 0
(water) or 1
(land). An island is a group of 1
s connected horizontally or vertically (not diagonally).
You may change at most one 0
to 1
(i.e., flip a water cell to land). After this change, you want to find the size of the largest possible island in the grid.
0
to 1
.n * n
.
At first glance, it might seem like we would need to try flipping every 0
to 1
and, for each, compute the size of the resulting largest island. However, this would be very inefficient for large grids.
Instead, we can break the problem into two main parts:
0
cell, consider flipping it and calculate the combined area of all distinct neighboring islands that would be connected through this flip.0
can only connect up to four neighboring islands.
The key insight is to uniquely label each island and store its area, so when checking a 0
cell, we can quickly sum the areas of unique adjacent islands.
1
, perform DFS or BFS to mark all connected 1
s with a unique island id (starting from 2 to avoid confusion with 0 and 1).{island_id: area}
.0
cell, look at its four neighbors. Collect the unique island ids (to avoid double-counting the same island).n * n
.1
s, flipping any 0
gives an island of size 1.Consider the input grid:
1 0 0 1
(0,0)
is a 1
: assign island id 2, area = 1.(1,1)
is a 1
: assign island id 3, area = 1.0
:
(0,1)
neighbors: (0,0)
(island 2), (1,1)
(island 3). If we flip (0,1)
, the connected area is 1 (flipped) + 1 (island 2) + 1 (island 3) = 3.(1,0)
also connects both islands; flipping it also yields area 3.0
, flip it and run DFS/BFS to find the largest island. This is O(n4), which is too slow for large grids.0
, checking up to 4 neighbors and summing: O(n2).The optimized approach is efficient and suitable for large grids.
By uniquely labeling each island and storing their areas, we can efficiently determine the effect of flipping any 0
cell. This avoids redundant computation and ensures that each possible flip is considered in constant time relative to the number of neighbors. The solution is both elegant and optimal for the problem constraints.