--- 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]] ``` -->