695. Max Area of Island - Explanation

Problem Link

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: 6

Explanation: 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.


Company Tags

Please upgrade to NeetCode Pro to view company tags.



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

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

  1. Initialize a visited set to track already counted cells.
  2. For each cell in the grid:
    • If it is land (1) and not visited, run dfs from it.
  3. dfs:
    • Stop if out of bounds, water (0), or already visited.
    • Mark the cell as visited.
    • Return 1 + area from all 4 neighbors.
  4. After each dfs call, update the maximum area.
  5. 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 area

Time & Space Complexity

  • Time complexity: O(mn)O(m * n)
  • Space complexity: O(mn)O(m * n)

Where mm is the number of rows and nn is the number of columns in the gridgrid.


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 0 to avoid revisiting
  • Track the largest island size found

Algorithm

  1. Iterate through every cell in the grid.
  2. When a land cell (1) is found:
    • Start bfs from that cell.
    • Mark it as visited by setting it to 0.
    • Initialize area count to 1.
  3. 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 it 0, and increase area.
  4. After bfs completes, update the maximum area.
  5. Continue scanning the grid.
  6. 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 area

Time & Space Complexity

  • Time complexity: O(mn)O(m * n)
  • Space complexity: O(mn)O(m * n)

Where mm is the number of rows and nn is the number of columns in the gridgrid.


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

  1. Treat each cell as a unique node using index = r * COLS + c.
  2. Initialize DSU with ROWS * COLS elements.
  3. Traverse the grid:
    • If the current cell is land (1):
      • Check its 4 neighbors.
      • If a neighbor is also land, union the two cells.
  4. After unions, for each land cell:
    • Find the size of its connected component.
    • Update the maximum area.
  5. 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 area

Time & Space Complexity

  • Time complexity: O(mn)O(m * n)
  • Space complexity: O(mn)O(m * n)

Where mm is the number of rows and nn is the number of columns in the gridgrid.


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.