<p>There is an <code>m x n</code> rectangular island that borders both the <strong>Pacific Ocean</strong> and <strong>Atlantic Ocean</strong>. The <strong>Pacific Ocean</strong> touches the island&#39;s left and top edges, and the <strong>Atlantic Ocean</strong> touches the island&#39;s right and bottom edges.</p>

<p>The island is partitioned into a grid of square cells. You are given an <code>m x n</code> integer matrix <code>heights</code> where <code>heights[r][c]</code> represents the <strong>height above sea level</strong> of the cell at coordinate <code>(r, c)</code>.</p>

<p>The island receives a lot of rain, and the rain water can flow to neighboring cells directly north, south, east, and west if the neighboring cell&#39;s height is <strong>less than or equal to</strong> the current cell&#39;s height. Water can flow from any cell adjacent to an ocean into the ocean.</p>

<p>Return <em>a <strong>2D list</strong> of grid coordinates </em><code>result</code><em> where </em><code>result[i] = [r<sub>i</sub>, c<sub>i</sub>]</code><em> denotes that rain water can flow from cell </em><code>(r<sub>i</sub>, c<sub>i</sub>)</code><em> to <strong>both</strong> the Pacific and Atlantic oceans</em>.</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>
<img alt="" src="https://assets.leetcode.com/uploads/2021/06/08/waterflow-grid.jpg" style="width: 400px; height: 400px;" />
<pre>
<strong>Input:</strong> heights = [[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]]
<strong>Output:</strong> [[0,4],[1,3],[1,4],[2,2],[3,0],[3,1],[4,0]]
<strong>Explanation:</strong> The following cells can flow to the Pacific and Atlantic oceans, as shown below:
[0,4]: [0,4] -&gt; Pacific Ocean 
&nbsp;      [0,4] -&gt; Atlantic Ocean
[1,3]: [1,3] -&gt; [0,3] -&gt; Pacific Ocean 
&nbsp;      [1,3] -&gt; [1,4] -&gt; Atlantic Ocean
[1,4]: [1,4] -&gt; [1,3] -&gt; [0,3] -&gt; Pacific Ocean 
&nbsp;      [1,4] -&gt; Atlantic Ocean
[2,2]: [2,2] -&gt; [1,2] -&gt; [0,2] -&gt; Pacific Ocean 
&nbsp;      [2,2] -&gt; [2,3] -&gt; [2,4] -&gt; Atlantic Ocean
[3,0]: [3,0] -&gt; Pacific Ocean 
&nbsp;      [3,0] -&gt; [4,0] -&gt; Atlantic Ocean
[3,1]: [3,1] -&gt; [3,0] -&gt; Pacific Ocean 
&nbsp;      [3,1] -&gt; [4,1] -&gt; Atlantic Ocean
[4,0]: [4,0] -&gt; Pacific Ocean 
       [4,0] -&gt; Atlantic Ocean
Note that there are other possible paths for these cells to flow to the Pacific and Atlantic oceans.
</pre>

<p><strong class="example">Example 2:</strong></p>

<pre>
<strong>Input:</strong> heights = [[1]]
<strong>Output:</strong> [[0,0]]
<strong>Explanation:</strong> The water can flow from the only cell to the Pacific and Atlantic oceans.
</pre>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>m == heights.length</code></li>
	<li><code>n == heights[r].length</code></li>
	<li><code>1 &lt;= m, n &lt;= 200</code></li>
	<li><code>0 &lt;= heights[r][c] &lt;= 10<sup>5</sup></code></li>
</ul>

class Solution {
private:
    void dfs(pair<int, int> node, vector<vector<int>>& vis,
             vector<vector<vector<pair<int,int>>>>& adj,
             vector<vector<int>>& pacific, vector<vector<int>>& atlantic, pair<int,int> parent, vector<vector<int>>& heights) {
        // if(parent.first!=-1 && heights[parent.first][parent.second] == heights[node.first][node.second]){
        //     vis[node.first][node.second] = 0;
        //     return;
        // }
        vis[node.first][node.second] = 1;
        
        for (auto n : adj[node.first][node.second]) {
            // if(node.first == 15 && (node.second == 2 || node.second == 1)){
            //     cout<<node.second<<"<=> "<<n.first<<":"<<n.second<<endl;
            // }
            if (!vis[n.first][n.second]) {
                dfs(n, vis, adj, pacific, atlantic, node, heights);
            } 
            // else {
            //     if(heights[node.first][node.second] == heights[n.first][n.second]){
            //         vis[n.first][n.second] = 0;
            //     }
            // }
            pacific[node.first][node.second] = pacific[n.first][n.second] == 1 ? 1: pacific[node.first][node.second];
            atlantic[node.first][node.second] = atlantic[n.first][n.second] == 1 ? 1:atlantic[node.first][node.second];
        // if(node.first == 15 && (node.second == 2 || node.second == 1)){
        //         cout<<node.second<<"=> "<<n.first<<":"<<n.second<<endl;
        //         cout<<pacific[node.first][node.second]<<" : "<<atlantic[node.first][node.second]<<endl;
        //     }
        }
        // if(node.first == 0 || node.second == 0){
        //     pacific[node.first][node.second] = 1;
        // }
        // if(node.first == atlantic.size()-1 || node.second == atlantic[0].size()-1){
        //     atlantic[node.first][node.second] = 1;
        // }
        if(parent.first!=-1 && heights[parent.first][parent.second] == heights[node.first][node.second]){
            vis[node.first][node.second] = 0;
            // return;
        }
    }

public:
    vector<vector<int>> pacificAtlantic(vector<vector<int>>& heights) {
        int rows = heights.size(), cols = heights[0].size();
        vector<vector<int>> pacific(rows, vector<int>(cols, 0));
        vector<vector<int>> atlantic(rows, vector<int>(cols, 0));
        vector<vector<int>> vis(rows, vector<int>(cols, 0));

        for (int i = 0; i < cols; i++) {
            pacific[0][i] = 1;
        }
        for (int i = 0; i < rows; i++) {
            pacific[i][0] = 1;
        }
        for (int i = 0; i < cols; i++) {
            atlantic[rows - 1][i] = 1;
        }
        for (int i = 0; i < rows; i++) {
            atlantic[i][cols - 1] = 1;
        }

        // unordered_map<pair<int, int>, vector<pair<int, int>>> adj;
        vector<vector<vector<pair<int,int>>>> adj(rows, vector<vector<pair<int,int>>>(cols, vector<pair<int,int>>()));
        vector<std::pair<int, int>> directions = {
            {-1, 0}, {0, 1}, {1, 0}, {0, -1}};

        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                // pair<int, int> current = {i, j};
                for (const auto& dir : directions) {
                    int ni = i + dir.first;
                    int nj = j + dir.second;
                    if (ni >= 0 && ni < rows && nj >= 0 && nj < cols) {
                        if (heights[i][j] >= heights[ni][nj]) {
                            adj[i][j].push_back({ni, nj});
                        }
                    }
                }
            }
        }

        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                if (!vis[i][j]) {
                    // cout<<"Starting: "<<i<<":"<<j<<endl;
                    dfs({i, j}, vis, adj, pacific, atlantic, {-1,-1}, heights);
                }
            }
        }

        // cout<<"HELLOOOO";

        vector<vector<int>> ans;
        for(int i=0;i<rows;i++){
            for(int j=0; j<cols; j++){
                if(pacific[i][j]==1 && atlantic[i][j]==1){
                    ans.push_back({i,j});
                    // ans[0].push_back(j);
                }
            }
        }

        return ans;
    }
};
42400