695. Max Area of Island - Explanation
Description
You are given a matrix grid where grid[i] is either a 0 (representing water) or 1 (representing land).
An island is defined as a group of 1'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 in grid. If no island exists, return 0.
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
Topics
Recommended Time & Space Complexity
You should aim for a solution with O(m * n) time and O(m * n) space, where m is the number of rows and n is the number of columns in the grid.
Hint 1
An island is a group of 1's in which every 1 is reachable from any other 1 in that group. Can you think of an algorithm that can find the number of groups by visiting a group only once? Maybe there is a recursive way of doing it.
Hint 2
We can use the Depth First Search (DFS) algorithm to traverse each group by starting at a cell with 1 and recursively visiting all the cells that are reachable from that cell and are also 1. Can you think about how to find the area of that island? How would you implement this?
Hint 3
We traverse the grid, and when we encounter a 1, we initialize a variable area. We then start a DFS from that cell to visit all connected 1's recursively, marking them as 0 to indicate they are visited. At each recursion step, we increment area. After completing the DFS, we update maxArea, which tracks the maximum area of an island in the grid, if maxArea < area. Finally, after traversing the grid, we return maxArea.
Prerequisites
Before attempting this problem, you should be comfortable with:
- Depth First Search (DFS) - Used to recursively explore all connected land cells in an island
- Breadth First Search (BFS) - An alternative traversal using a queue to explore islands level by level
- Graph Traversal on Grids - Treating 2D grids as graphs where adjacent cells are connected
- Union-Find (Disjoint Set Union) - An advanced technique for grouping connected components efficiently
1. Depth First Search
Intuition
An island is a group of connected 1s.
To find the maximum area, we explore each island fully and count how many cells it contains.
Depth First Search (dfs) helps us:
- Start from a land cell
- Visit all connected land cells (up, down, left, right)
- Count the size of that island
- Keep track of the largest size seen
We mark cells as visited so we don't count the same cell twice.
Algorithm
- Initialize a visited set to track already counted cells.
- For each cell in the grid:
- If it is land (
1) and not visited, rundfsfrom it.
- If it is land (
dfs:- Stop if out of bounds, water (
0), or already visited. - Mark the cell as visited.
- Return
1 + area from all 4 neighbors.
- Stop if out of bounds, water (
- After each
dfscall, update the maximum area. - Return the maximum area found.
class Solution:
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
ROWS, COLS = len(grid), len(grid[0])
visit = set()
def dfs(r, c):
if (r < 0 or r == ROWS or c < 0 or
c == COLS or grid[r][c] == 0 or
(r, c) in visit
):
return 0
visit.add((r, c))
return (1 + dfs(r + 1, c) +
dfs(r - 1, c) +
dfs(r, c + 1) +
dfs(r, c - 1))
area = 0
for r in range(ROWS):
for c in range(COLS):
area = max(area, dfs(r, c))
return areaTime & Space Complexity
- Time complexity:
- Space complexity:
Where is the number of rows and is the number of columns in the .
2. Breadth First Search
Intuition
An island is a group of connected 1s.
To find the maximum area, we explore each island completely and count how many cells it has.
Using Breadth First Search (bfs):
- Start from a land cell (
1) - Visit all connected land cells level by level
- Count each visited cell as part of the island
- Mark cells as
0to avoid revisiting - Track the largest island size found
Algorithm
- Iterate through every cell in the grid.
- When a land cell (
1) is found:- Start
bfsfrom that cell. - Mark it as visited by setting it to
0. - Initialize area count to
1.
- Start
- During
bfs:- Pop a cell from the queue.
- Check its 4 neighbors (up, down, left, right).
- If a neighbor is valid land (
1), add it to the queue, mark it0, and increase area.
- After
bfscompletes, update the maximum area. - Continue scanning the grid.
- Return the maximum area found.
class Solution:
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
directions = [[1, 0], [-1, 0], [0, 1], [0, -1]]
ROWS, COLS = len(grid), len(grid[0])
area = 0
def bfs(r, c):
q = deque()
grid[r][c] = 0
q.append((r, c))
res = 1
while q:
row, col = q.popleft()
for dr, dc in directions:
nr, nc = dr + row, dc + col
if (nr < 0 or nc < 0 or nr >= ROWS or
nc >= COLS or grid[nr][nc] == 0
):
continue
q.append((nr, nc))
grid[nr][nc] = 0
res += 1
return res
for r in range(ROWS):
for c in range(COLS):
if grid[r][c] == 1:
area = max(area, bfs(r, c))
return areaTime & Space Complexity
- Time complexity:
- Space complexity:
Where is the number of rows and is the number of columns in the .
3. Disjoint Set Union
Intuition
Think of each land cell (1) as a node in a graph.
If two land cells are adjacent (up, down, left, right), they belong to the same island.
Using Disjoint Set Union (Union-Find):
- Each land cell starts as its own component
- When two neighboring land cells are found, we union them
- The size of a connected component represents the area of that island
- Track the maximum component size
This approach is useful when you want to group connected components efficiently.
Algorithm
- Treat each cell as a unique node using
index = r * COLS + c. - Initialize DSU with
ROWS * COLSelements. - Traverse the grid:
- If the current cell is land (
1):- Check its
4neighbors. - If a neighbor is also land, union the two cells.
- Check its
- If the current cell is land (
- After unions, for each land cell:
- Find the size of its connected component.
- Update the maximum area.
- Return the maximum area found.
class DSU:
def __init__(self, n):
self.Parent = list(range(n + 1))
self.Size = [1] * (n + 1)
def find(self, node):
if self.Parent[node] != node:
self.Parent[node] = self.find(self.Parent[node])
return self.Parent[node]
def union(self, u, v):
pu = self.find(u)
pv = self.find(v)
if pu == pv:
return False
if self.Size[pu] >= self.Size[pv]:
self.Size[pu] += self.Size[pv]
self.Parent[pv] = pu
else:
self.Size[pv] += self.Size[pu]
self.Parent[pu] = pv
return True
def getSize(self, node):
par = self.find(node)
return self.Size[par]
class Solution:
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
ROWS, COLS = len(grid), len(grid[0])
dsu = DSU(ROWS * COLS)
def index(r, c):
return r * COLS + c
directions = [(1, 0), (-1, 0), (0, 1), (0, -1)]
area = 0
for r in range(ROWS):
for c in range(COLS):
if grid[r][c] == 1:
for dr, dc in directions:
nr, nc = r + dr, c + dc
if (nr < 0 or nc < 0 or nr >= ROWS or
nc >= COLS or grid[nr][nc] == 0
):
continue
dsu.union(index(r, c), index(nr, nc))
area = max(area, dsu.getSize(index(r, c)))
return areaTime & Space Complexity
- Time complexity:
- Space complexity:
Where is the number of rows and is the number of columns in the .
Common Pitfalls
Forgetting to Mark Cells as Visited
A common mistake is not marking cells as visited before or immediately after processing them. This leads to infinite recursion in DFS or infinite loops in BFS, as the same cell gets added to the queue or call stack repeatedly. Always mark a cell as visited (either by using a separate visited set or by modifying the grid value to 0) before exploring its neighbors.
Incorrect Boundary Checks
Failing to properly check grid boundaries before accessing grid[r][c] causes index-out-of-bounds errors. The order of conditions matters: always check r >= 0 && r < ROWS && c >= 0 && c < COLS before checking grid[r][c]. Short-circuit evaluation prevents the array access when indices are invalid.
Counting Area Incorrectly in BFS
In BFS, a subtle bug occurs when you increment the area count at the wrong time. The area should be incremented when a cell is added to the queue and marked as visited, not when it is dequeued. If you increment when dequeuing, you may count the same cell multiple times if it gets added to the queue from different neighbors before being processed.
Sign in to join the discussion