Home

Back

This is a solution to LeetCode 417 — Pacific Atlantic Water Flow

Intuition#

The statement “Water can flow from any cell adjacent to an ocean into the ocean” suggests that to determine whether a cell can reach an ocean, we only need to check whether it can reach the coastline.

Viewed as a graph problem, each cell is a node and there is a directed edge from A to B when A and B are adjacent and height(A) >= height(B). The task becomes finding all nodes that can reach any coastline node.

However, explicitly building an adjacency matrix is wasteful for large grids (up to 200×200). A simpler and more efficient idea is to reverse the search: instead of asking which nodes can reach the coast, start from the coast and explore inward. In the reversed graph, every node reachable from the coast corresponds to a node that can flow to that coast in the original graph. So we can run a flood fill from each ocean’s coast and mark all cells reachable under the non-decreasing-height constraint.

Approach#

Run BFS or DFS from all coast cells for each ocean — once for the Pacific and once for the Atlantic. The answers are the cells that are reachable from both searches (intersection of the two reachable sets).

Code#

from collections import deque

class Solution:
    def pacificAtlantic(self, heights: List[List[int]]) -> List[List[int]]:
        if not heights or not heights[0]:
            return []
        rows, cols = len(heights), len(heights[0])
        if rows == 1 or cols == 1:
            return [[i, j] for i in range(rows) for j in range(cols)]

        def bfs(starts):
            q = deque(starts)
            seen = [[False]*cols for _ in range(rows)]
            for r, c in starts:
                seen[r][c] = True
            while q:
                r, c = q.popleft()
                h = heights[r][c]
                for dr, dc in ((1,0),(-1,0),(0,1),(0,-1)):
                    nr, nc = r + dr, c + dc
                    if 0 <= nr < rows and 0 <= nc < cols and not seen[nr][nc] and heights[nr][nc] >= h:
                        seen[nr][nc] = True
                        q.append((nr, nc))
            return seen

        pac_starts = [(0, c) for c in range(cols)] + [(r, 0) for r in range(rows)]
        atl_starts = [(rows - 1, c) for c in range(cols)] + [(r, cols - 1) for r in range(rows)]

        pac_seen = bfs(pac_starts)
        atl_seen = bfs(atl_starts)

        res = [[r, c] for r in range(rows) for c in range(cols) if pac_seen[r][c] and atl_seen[r][c]]
        
        return res
python