---
# System prepended metadata

title: '[417. Pacific Atlantic Water Flow](https://leetcode.com/problems/pacific-atlantic-water-flow/)'
tags: [leetcode]

---

---
tags: leetcode
---

# [417. Pacific Atlantic Water Flow](https://leetcode.com/problems/pacific-atlantic-water-flow/)
---
# My Solution
## Solution 1: DFS
### The Key Idea for Solving This Coding Question
### C++ Code
```cpp=
class Solution {
public:
    vector<vector<int>> pacificAtlantic(vector<vector<int>> &heights) {
        rows = heights.size();
        cols = heights[0].size();

        vector<vector<bool>> pacificReachable(rows, vector<bool>(cols, false));
        vector<vector<bool>> atlanticReachable(rows, vector<bool>(cols, false));

        for (int r = 0; r < rows; ++r) {
            dfs(heights, pacificReachable, r, 0);
            dfs(heights, atlanticReachable, r, cols - 1);
        }
        for (int c = 0; c < cols; ++c) {
            dfs(heights, pacificReachable, 0, c);
            dfs(heights, atlanticReachable, rows - 1, c);
        }

        vector<vector<int>> answer;
        for (int r = 0; r < rows; ++r) {
            for (int c = 0; c < cols; ++c) {
                if (pacificReachable[r][c] && atlanticReachable[r][c]) {
                    answer.push_back({r, c});
                }
            }
        }

        return answer;
    }

private:
    int rows;
    int cols;

    void dfs(vector<vector<int>> &heights, vector<vector<bool>> &reachable, int r, int c) {
        reachable[r][c] = true;
        vector<vector<int>> dirs = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};

        for (auto &dir : dirs) {
            int nextR = r + dir[0], nextC = c + dir[1];
            if (nextR < 0 || rows <= nextR || nextC < 0 || cols <= nextC ||
                reachable[nextR][nextC] || heights[nextR][nextC] < heights[r][c]) {
                continue;
            }
            dfs(heights, reachable, nextR, nextC);
        }
    }
};
```
### Time Complexity
$O(mn)$
* $m$ is the number of rows of `heights`.
* $n$ is the number of columns of `heights`.
### Space Complexity
$O(mn)$
* $m$ is the number of rows of `heights`.
* $n$ is the number of columns of `heights`.
## Solution 2: BFS
### The Key Idea for Solving This Coding Question
### C++ Code
```cpp=
struct cellData {
    int r;
    int c;
    cellData(int r, int c) : r(r), c(c) {} 
};

class Solution {
public:
    vector<vector<int>> pacificAtlantic(vector<vector<int>> &heights) {
        rows = heights.size();
        cols = heights[0].size();

        vector<vector<bool>> pacificReachable(rows, vector<bool>(cols, false));
        vector<vector<bool>> atlanticReachable(rows, vector<bool>(cols, false));
        queue<cellData> pacificQ, atlanticQ;

        for (int r = 0; r < rows; ++r) {
            pacificQ.push(cellData(r, 0));
            pacificReachable[r][0] = true;

            atlanticQ.push(cellData(r, cols - 1));
            atlanticReachable[r][cols - 1] = true;
        }
        for (int c = 0; c < cols; ++c) {
            pacificQ.push(cellData(0, c));
            pacificReachable[0][c] = true;

            atlanticQ.push(cellData(rows - 1, c));
            atlanticReachable[rows - 1][c] = true;
        }

        bfs(heights, pacificQ, pacificReachable);
        bfs(heights, atlanticQ, atlanticReachable);

        vector<vector<int>> answer;
        for (int r = 0; r < rows; ++r) {
            for (int c = 0; c < cols; ++c) {
                if (pacificReachable[r][c] && atlanticReachable[r][c]) {
                    answer.push_back({r, c});
                }
            }
        }

        return answer;
    }

private:
    int rows;
    int cols;

    void bfs(vector<vector<int>> &heights, queue<cellData> &q, vector<vector<bool>> &reachable) {
        vector<vector<int>> dirs = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};

        while (!q.empty()) {
            cellData curr = q.front();
            q.pop();

            for (auto &dir : dirs) {
                int nextR = curr.r + dir[0], nextC = curr.c + dir[1];
                if (nextR < 0 || rows <= nextR || nextC < 0 || cols <= nextC ||
                    reachable[nextR][nextC] || 
                    heights[curr.r][curr.c] > heights[nextR][nextC]) {
                    continue;
                }
                q.push(cellData(nextR, nextC));
                reachable[nextR][nextC] = true;
            }
        }
    }
};
```
### Time Complexity
$O(mn)$
* $m$ is the number of rows of `heights`.
* $n$ is the number of columns of `heights`.
### Space Complexity
$O(mn)$
* $m$ is the number of rows of `heights`.
* $n$ is the number of columns of `heights`.
# Miscellane
<!--
# Test Cases
```
[[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]]
```
```
[[1]]
```
```
[[2,1],[1,2]]
```
* Runtime Error
```
[[1,2,3,4,5,6,7,8],[28,29,30,31,32,33,34,9],[27,48,49,50,51,52,35,10],[26,47,60,61,62,53,36,11],[25,46,59,64,63,54,37,12],[24,45,58,57,56,55,38,13],[23,44,43,42,41,40,39,14],[22,21,20,19,18,17,16,15]]
```
-->