LeetCode link: 827. Making A Large Island
You are given an n x n binary matrix grid. You are allowed to change at most one 0 to be 1.
Return the size of the largest island in grid after applying this operation.
An island is a 4-directionally connected group of 1s.
Input: grid = [
[1,0],
[0,1]
]
Output: 3
Explanation: Change one 0 to 1 and connect two 1s, then we get an island with area = 3.
Input: grid = [
[1,1],
[1,0]
]
Output: 4
Explanation: Change the 0 to 1 and make the island bigger, only one island with area = 4.
Input: grid = [
[1,1],
[1,1]
]
Output: 4
Explanation: Can't change any 0 to 1, only one island with area = 4.
n == grid.lengthn == grid[i].length1 <= n <= 500grid[i][j]is either0or1.
This problem is hard. Before solving this problem, you can do the following two problems first:
The island problem can be abstracted into a graph theory problem. This is an undirected graph:
And this graph may have multiple connected components (islands):
- Change one vertex from
0to1to make the largest island means combining the adjacent islands of a0vertex. - We can mark an island's lands with one same id (
island_id), and mark another island's lands with anotherisland_id. To mark a land, just change its value to theisland_id. - Use a
map(or anarray) to map eachisland_idto itsarea. - How to calculate the area of an island? Using
Depth-First SearchorBreadth-First Search. See 695. Max Area of Island. - Iterate through each
0(water), then sum theareasof neighboring islands. - Record the max area and return it.
- Time:
O(n * n). - Space:
O(n * n).
from collections import defaultdict
class Solution:
def __init__(self):
self.island_id = 2
self.island_id_to_area = defaultdict(int)
def largestIsland(self, grid: List[List[int]]) -> int:
self.grid = grid
max_area = 0
for i in range(len(grid)):
for j in range(len(grid[0])):
if self.grid[i][j] == 1:
self.depth_first_search(i, j)
self.island_id += 1
has_water = False
for i in range(len(grid)):
for j in range(len(grid[0])):
if self.grid[i][j] == 0:
has_water = True
max_area = max(max_area, self.combined_islands_area(i, j))
if not has_water:
return len(grid) * len(grid[0])
return max_area
def depth_first_search(self, i, j):
if i < 0 or j < 0 or i >= len(self.grid) or j >= len(self.grid[0]):
return
if self.grid[i][j] != 1:
return
self.grid[i][j] = self.island_id
self.island_id_to_area[self.island_id] += 1
for a, b in [
(-1, 0),
(0, -1), (0, 1),
(1, 0)
]:
m = i + a
n = j + b
self.depth_first_search(m, n)
def combined_islands_area(self, i, j):
island_ids = set()
for a, b in [
(-1, 0),
(0, -1), (0, 1),
(1, 0)
]:
m = i + a
n = j + b
if m < 0 or n < 0 or m >= len(self.grid) or n >= len(self.grid[0]):
continue
if self.grid[m][n] != 0:
island_ids.add(self.grid[m][n])
area = 1
for island_id in island_ids:
area += self.island_id_to_area[island_id]
return area// Welcome to create a PR to complete the code of this language, thanks!// Welcome to create a PR to complete the code of this language, thanks!// Welcome to create a PR to complete the code of this language, thanks!// Welcome to create a PR to complete the code of this language, thanks!// Welcome to create a PR to complete the code of this language, thanks!# Welcome to create a PR to complete the code of this language, thanks!// Welcome to create a PR to complete the code of this language, thanks!// Welcome to create a PR to complete the code of this language, thanks!// Welcome to create a PR to complete the code of this language, thanks!// Welcome to create a PR to complete the code of this language, thanks!// Welcome to create a PR to complete the code of this language, thanks!
