Max Area of Island Solution
Given an m × n binary grid, return the maximum area (number of cells) of any island. An island is a 4-directionally connected group of 1s.
Problem Statement
Given a binary matrix grid of 0s (water) and 1s (land), return the maximum area of an island. An island is formed by connecting adjacent land cells horizontally or vertically. If there are no islands, return 0.
DFS With Visited Array — O(m·n)
Scan every cell. When an unvisited land cell is found, run DFS to count all connected land cells (the island area). Track visited cells in a separate boolean grid. Update the global maximum after each DFS.
Each DFS counts exactly one connected component. The outer loop finds each component exactly once (only unvisited cells trigger a DFS). Taking the max across all components gives the answer.
0 in-place — the "sink" pattern from LC 200. This reduces extra space to O(1) (only the DFS call stack remains).
| Metric | Value |
|---|---|
| Time | O(m · n) |
| Space | O(m · n) — visited array + O(m·n) DFS stack worst case |
In-place DFS — O(m·n) time, O(1) extra space
Modify the grid in-place: when visiting a cell, set it to 0 to mark it as visited. Count cells as the DFS returns up the call stack. The grid is restored to water-state for visited cells, which is acceptable since the problem doesn't require preserving input.
- Scan all cells in row-major order.
- When
grid[r][c] == 1: calldfs(r, c), update global max. dfs(r, c): if out of bounds or cell is 0, return 0.- Set
grid[r][c] = 0to mark visited, then return1 + dfs(4 neighbors).
- "Maximum/total area of connected regions in a grid." The DFS-return-count pattern (return 1 + recursive calls) is the standard area accumulator.
- Used directly in LC 200 (count components instead of area), and extended in LC 1020 (count cells not reachable from boundary) and LC 827 (Making A Large Island — max area after flipping one 0).
- Each call to
dfs(r, c)represents "I am visiting one cell." The1counts the current cell. - The recursive calls count all cells reachable from neighbors.
- Since cells are zeroed before recursing, no cell is double-counted.
- The sum propagates up through the call stack — the root call returns the total island area.
Visual Walkthrough
Trace on a 3×4 grid with two islands. DFS from (0,2) finds area 4.
Code — Java & Python
Complexity Analysis
| Approach | Time | Space | Trade-off |
|---|---|---|---|
| DFS + visited boolean array | O(m · n) | O(m · n) | Preserves input; extra O(m·n) space |
| BFS in-place | O(m · n) | O(min(m,n)) queue | Iterative — no stack overflow risk; more code |
| DFS in-place ← optimal | O(m · n) | O(m · n) DFS stack | Minimal code; mutates input acceptably; elegant return-1+neighbors pattern |
- In the worst case (all land, single snake-shaped island of 2500 cells), DFS stack depth = 2500 — safe for the given constraints (50×50).
- For grids up to 300×300 (LC 200), BFS is the safer choice to avoid stack overflow.
Edge Cases & Pitfalls
| Case | Input | Why It Matters |
|---|---|---|
| All water | All 0s | No DFS triggered. Return 0. |
| All land | All 1s | One giant island. DFS from (0,0) returns m·n. |
| 1×1 land | [[1]] | dfs returns 1. max=1. |
| Two equal-sized islands | Two separate 3-cell islands | DFS for each returns 3. Max stays 3. |
| Diagonal land cells | 1s only diagonally adjacent | Diagonal adjacency is not connected — each diagonal cell is a separate island of size 1. |
| Input uses chars vs ints | '0'/'1' vs 0/1 | LC 200 uses chars; LC 695 uses ints. Check comparison: == 1 not == '1'. |
max() without a default. In Python, max(empty_iterable) raises a ValueError. Always provide default=0 — the answer is 0 if no islands exist. Alternatively, initialize maxArea = 0 and update it only when a land cell is found.