<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 {
public:
    vector<vector<int>> pacificAtlantic(vector<vector<int>>& heights) {
        // vector<vector<int>> res;
        // queue<vector<int>> q;


        // int n = heights.size();
        // int m = heights[0].size();
        // vector<vector<pair<int,int>>> possibe(n,vector<pair<int,int>>(m,{0,0}));


       
        // q.push({n-1,0,1,1});
        // q.push({0,m-1,1,1});
        // int i=n-2;
        // while(i>=0)
        // {
        //     if(heights[i][0]<heights[n-1][0])
        //     break;
        //     possibe[i][0] = {1,1};
        //     possibe[i][m-1]={0,1};
        //     q.push({i,0,1,1});
        //     i--;

        // }
        // while(i>=0)
        // {
        //     possibe[i][0] = {1,0};
        //     possibe[i][m-1]={0,1};
        //     q.push({i,0,1,0});
        //     i--;
        // }
        // int j= m-2;
        // while(j>=0)
        // {
        //     if(heights[0][j]<heights[0][m-1])
        //     break;
        //     possibe[0][j] = {1,1};
        //     possibe[n-1][j] = {0,1};

        //     q.push({0,j});
        //     j--;

        // }
        // while(j>=0)
        // {
        //     possibe[0][j] = {1,0};
        //     possibe[n-1][j] = {0,1};
        //     q.push({0,j,0,1});
        //     j--;
        // }
        // possibe[n-1][0] = {1,1};
        // possibe[0][m-1] = {1,1};
        //        int x =0 ;

        // while(x<200){

        // for(int i = 0 ;i<n;i++)
        // {
        //     for(int j= 0 ; j<m;j++)
        //     {
        //         int is_pacific = possibe[i][j].first;
        //         int is_atlantic = possibe[i][j].second;
        //         vector<pair<int,int>> directions = {{0,1},{1,0},{-1,0},{0,-1}};
        //         cout<<i<<" "<<j<<" "<<possibe[i][j].first<<" "<<possibe[i][j].second<<endl;
        //         if(!is_pacific)
        //         {
        //             for(pair<int,int> dir : directions)
        //             {
        //                 if(i+dir.first <0 || i+dir.first>=n || j + dir.second<0 || j + dir.second>=m || heights[i][j]<heights[i+dir.first][j+dir.second] || !possibe[i+dir.first][j+dir.second].first)
        //                 continue;
        //                 possibe[i][j].first =1;
        //                 break;
                        
        //             }
        //         }
        //         if(!is_atlantic)
        //         {
        //             for(pair<int,int> dir : directions)
        //             {
        //                 if(i+dir.first <0 || i+dir.first>=n || j + dir.second<0 || j + dir.second>=m || heights[i][j]<heights[i+dir.first][j+dir.second] || !possibe[i+dir.first][j+dir.second].second)
        //                 continue;
        //                 possibe[i][j].second =1;
        //                 break;
                        
        //             }
        //         }
        //         cout<<i<<" "<<j<<" "<<possibe[i][j].first<<" "<<possibe[i][j].second<<endl;


        //     }
        // }
        //         x++;
        // }
 
        // for(int i = 0 ;i<n;i++)
        // {
        //     for(int j= 0 ; j<m;j++)
        //     {
        //         int is_pacific = possibe[i][j].first;
        //         int is_atlantic = possibe[i][j].second;
        //             vector<pair<int,int>> directions = {{0,1},{1,0},{-1,0},{0,-1}};
        //         if(!is_pacific)
        //         {
        //             for(pair<int,int> dir : directions)
        //             {
        //                 if(i+dir.first <0 || i+dir.first>=n || j + dir.second<0 || j + dir.second>=m || heights[i][j]<heights[i+dir.first][j+dir.second] || !possibe[i+dir.first][j+dir.second].first)
        //                 continue;
        //                 possibe[i][j].first =1;
        //                 break;
                        
        //             }
        //         }
        //         if(!is_atlantic)
        //         {
        //             for(pair<int,int> dir : directions)
        //             {
        //                 if(i+dir.first <0 || i+dir.first>=n || j + dir.second<0 || j + dir.second>=m || heights[i][j]<heights[i+dir.first][j+dir.second] || !possibe[i+dir.first][j+dir.second].second)
        //                 continue;
        //                 possibe[i][j].second =1;
        //                 break;
                        
        //             }
        //         }

        //         if(possibe[i][j].second  && possibe[i][j].first)
        //         res.push_back({i,j});
        //     }
        // }


        

        
        // return res;

    vector<vector<int>> res;

    unordered_map<int,unordered_map<int,int>> pacific,atlantic;

    queue<pair<int,int>> q;
    int n = heights.size();
    int m = heights[0].size();

    for(int i=0;i<n;i++)
    q.push({i,0});

    for(int j=1;j<m;j++)
    q.push({0,j});

    unordered_map<int,unordered_map<int,bool>> vis;

    while(!q.empty())
    {
        pair<int,int> x = q.front();
        q.pop();

        if(vis[x.first][x.second])
        continue;
        vis[x.first][x.second] = true;

        pacific[x.first][x.second]++;
        vector<pair<int,int>> directions = {{0,1},{1,0},{-1,0},{0,-1}};

        for(pair<int,int> dir : directions)
        {
            int new_x = x.first + dir.first;
            int new_y = x.second + dir.second;

            if(new_x<0 || new_x >=n || new_y < 0 || new_y >=m || heights[x.first][x.second] >heights[new_x][new_y] || vis[new_x][new_y])
            continue;

            q.push({new_x,new_y});


        }

    } 

    vis.clear();

    for(int i=0;i<n;i++)
    q.push({i,m-1});

    for(int j=0;j<m-1;j++)
    q.push({n-1,j});

    while(!q.empty())
    {
        pair<int,int> x = q.front();
        q.pop();

        if(vis[x.first][x.second])
        continue;
        vis[x.first][x.second] = true;

        atlantic[x.first][x.second]++;
        vector<pair<int,int>> directions = {{0,1},{1,0},{-1,0},{0,-1}};

        for(pair<int,int> dir : directions)
        {
            int new_x = x.first + dir.first;
            int new_y = x.second + dir.second;

            if(new_x<0 || new_x >=n || new_y < 0 || new_y >=m || heights[x.first][x.second] >heights[new_x][new_y] || vis[new_x][new_y])
            continue;

            q.push({new_x,new_y});


        }

    } 

    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
        {
            if(pacific[i][j] && atlantic[i][j])
            res.push_back({i,j});
        }
    }


    return res;
    


    }
};
44400