Problem
Question
You are given a matrix
gridwheregrid[i]is either a0(representing water) or1(representing land). An island is defined as a group of1’s connected horizontally or vertically. You may assume all four edges of the grid are surrounded by water. The area of an island is defined as the number of cells within the island. Return the maximum area of an island ingrid. If no island exists, return0.
Example 1:
Input: grid = [
[0,1,1,0,1],
[1,0,1,0,1],
[0,1,1,0,1],
[0,1,0,0,1]
]
Output: 6Explanation: 1’s cannot be connected diagonally, so the maximum area of the island is 6.
Constraints:
1 <= grid.length, grid[i].length <= 50
Solutions
1. 🏆 Depth-First Search
Time Complexity: | Space Complexity:
We can solve the problem using Depth-First Search (DFS). This method explores each cell in the grid with a value of 1 that hasn’t been visited. DFS recursively visits all connected land cells to calculate the total area of an island by following these steps:
- If the cell is out of bounds, return 0.
- If the cell is already visited or is water, return 0.
- Otherwise, explore all neighboring cells.
class Solution:
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
visited = set()
def dfs(x, y):
if x < 0 or y < 0 or x >= len(grid) or y >= len(grid[0]):
return 0
if (x, y) in visited or grid[x][y] == 0:
return 0
visited.add((x, y))
area = 1
area += dfs(x + 1, y)
area += dfs(x - 1, y)
area += dfs(x, y + 1)
area += dfs(x, y - 1)
return area
maximum = 0
for i in range(len(grid)):
for j in range(len(grid[0])):
if grid[i][j] == 1 and (i, j) not in visited:
maximum = max(maximum, dfs(i, j))
return maximum
2. Breadth-First Search
Time Complexity: | Space Complexity:
A similar solution is achieved through BFS:
- Start from an unvisited land cell and add it to the queue.
- For each cell, check if it’s out of bounds; if so, skip it.
- Otherwise, mark it as visited, count it, and add all unvisited neighbors to the queue.
- Keep traversing through the queue.
class Solution:
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
visited = set()
directions = [(1, 0), (-1, 0), (0, 1), (0, -1)]
def bfs(x, y):
queue = deque([(x, y)])
visited.add((x, y))
area = 0
while queue:
cx, cy = queue.popleft()
area += 1
for dx, dy in directions:
nx, ny = cx + dx, cy + dy
if 0 <= nx < len(grid) and 0 <= ny < len(grid[0]) and (nx, ny) not in visited and grid[nx][ny] == 1:
visited.add((nx, ny))
queue.append((nx, ny))
return area
maximum = 0
for i in range(len(grid)):
for j in range(len(grid[0])):
if grid[i][j] == 1 and (i, j) not in visited:
maximum = max(maximum, bfs(i, j))
return maximum
3. Union-Find
Time Complexity: | Space Complexity:
Using a Union-Find data structure, also known as Disjoint Set Union (DSU), we can connect all islands together in a graph, while keeping their areas in the supplemental area dictionary.
To understand the Union-Find data structure, refer to the video .
The find operation helps identify the root of each set, while union merges two sets and updates their areas, using path compression and union by rank for optimal performance. What is a path compression? Path compression is an optimization technique that flattens the structure of the tree whenever find is called, by making nodes point directly to the root.

class Solution:
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
if not grid:
return 0
rows, cols = len(grid), len(grid[0])
parent = {}
rank = {}
area = {}
def find(x):
if parent[x] != x:
parent[x] = find(parent[x])
return parent[x]
def union(x, y):
rootX = find(x)
rootY = find(y)
if rootX != rootY:
if rank[rootX] > rank[rootY]:
parent[rootY] = rootX
area[rootX] += area[rootY]
elif rank[rootX] < rank[rootY]:
parent[rootX] = rootY
area[rootY] += area[rootX]
else:
parent[rootY] = rootX
rank[rootX] += 1
area[rootX] += area[rootY]
for i in range(rows):
for j in range(cols):
if grid[i][j] == 1:
parent[(i, j)] = (i, j)
rank[(i, j)] = 0
area[(i, j)] = 1
for i in range(rows):
for j in range(cols):
if grid[i][j] == 1:
for ni, nj in [(i + 1, j), (i - 1, j), (i, j + 1), (i, j - 1)]:
if 0 <= ni < rows and 0 <= nj < cols and grid[ni][nj] == 1:
union((i, j), (ni, nj))
return max(area.values(), default=0)