class Solution:
def largestIsland(self, grid: List[List[int]]) -> int:
# Common items
N = len(grid)
# island-label -> island-size mapping
island_sizes = defaultdict(int)
next_land_label = 2
# maximum connection possibly by flipping one cell
# 1 can be case when all cells are 0
res = 1
neighbor_incs = [[0, 1], [0, -1], [1, 0], [-1, 0]]
"""
Stage 1:
Scan grid. Identify and uniquely label each island.
At the same time, also find and save the size of the island, retrievable by its label (in hashmap/dictionary)
Also, keep storing the maximum size island you have seen so far. (in variable)
"""
for r in range(N):
for c in range(N):
if grid[r][c] == 1:
island_sizes[next_land_label] = self._dfs(r, c, N, next_land_label, grid, neighbor_incs)
res = max(res, island_sizes[next_land_label])
next_land_label += 1
"""
Stage 2:
Flip each possible water cell to land.
For each water cell, count how many islands it can connect to via its 4 neighbors.
Keep updating the result.
"""
for r in range(N):
for c in range(N):
if grid[r][c] == 0:
connected_size_here = self._make_connection(r, c, N, grid, island_sizes, neighbor_incs)
res = max(res, connected_size_here)
return res
"""
Stage 1 work
DFS to find size of island, label island
"""
def _dfs(self, r, c, N, label, grid, neighbor_incs):
island_size = 0
if self.is_within_bounds(r, c, N) and grid[r][c] == 1:
grid[r][c] = label
island_size = 1
for r_inc, c_inc in neighbor_incs:
island_size += self._dfs(r + r_inc, c + c_inc, N, label, grid, neighbor_incs)
return island_size
"""
Stage 2 work
Make connection among the 4 possible islands.
"""
def _make_connection(self, r, c, N, grid, island_sizes, neighbor_incs):
seen_land_labels = set()
connected_size_here = 1
for r_inc, c_inc in neighbor_incs:
r_new = r + r_inc
c_new = c + c_inc
if (
self.is_within_bounds(r_new, c_new, N)
and grid[r_new][c_new] > 1 and grid[r_new][c_new] not in seen_land_labels
):
connected_size_here += island_sizes[grid[r_new][c_new]]
seen_land_labels.add(grid[r_new][c_new])
return connected_size_here
"""
Coordinate check to be within grid
"""
def is_within_bounds(self, r, c, N):
return r >= 0 and r < N and c >= 0 and c < N