Pacific Atlantic Water Flow

BFS/DFS from each ocean's edge cells upward — intersection of reachable sets is the answer.

Medium
Time O(m * n) Space O(m * n)
LeetCode
6 min read
bfs dfs matrix graph

Problem#

In a heights grid, water flows to lower-or-equal cells. The Pacific borders the top and left edges; the Atlantic borders the bottom and right. Return all cells from which water can reach both oceans.

Examples#

  • [[1,2,2,3,5],[3,2,3,4,4],[2,4,5,3,1],[6,7,1,4,5],[5,1,1,2,4]] → cells including [[0,4],[1,3],[1,4],[2,2],[3,0],[3,1],[4,0]].

Constraints#

  • 1 <= m, n <= 200.

Approach#

Reverse the flow: from each ocean’s border cells, BFS uphill to mark all cells whose water can flow into that ocean. Intersect the two reachability sets.

Solution#

Pacific Atlantic Water Flow
class Solution {
public:
vector<vector<int>> pacificAtlantic(vector<vector<int>>& h) {
int m = h.size(), n = h[0].size();
vector<vector<int>> pac(m, vector<int>(n, 0)), atl = pac;
int dr[4] = {-1, 1, 0, 0}, dc[4] = {0, 0, -1, 1};
function<void(int,int,vector<vector<int>>&)> dfs = [&](int r, int c, vector<vector<int>>& vis) {
vis[r][c] = 1;
for (int k = 0; k < 4; ++k) {
int nr = r + dr[k], nc = c + dc[k];
if (nr < 0 || nr >= m || nc < 0 || nc >= n) continue;
if (vis[nr][nc] || h[nr][nc] < h[r][c]) continue;
dfs(nr, nc, vis);
}
};
for (int i = 0; i < m; ++i) { dfs(i, 0, pac); dfs(i, n - 1, atl); }
for (int j = 0; j < n; ++j) { dfs(0, j, pac); dfs(m - 1, j, atl); }
vector<vector<int>> ans;
for (int i = 0; i < m; ++i)
for (int j = 0; j < n; ++j)
if (pac[i][j] && atl[i][j]) ans.push_back({i, j});
return ans;
}
};

Editorial#

The reverse-flow trick is the key — starting at the oceans and walking uphill is symmetric to “can this cell flow to the ocean?” and avoids re-running BFS per cell. Each cell is visited at most twice.

Complexity#

  • Time: O(m * n).
  • Space: O(m * n).

Concept revision#

Search ESC

Keyboard shortcuts

Shortcuts are disabled while typing in inputs.