• 417. Pacific Atlantic Water Flow


    问题:

    给定一个二维数组,代表一块大陆的海拔,

    数组左边和上边为太平洋,右边和下边为大西洋,

    对于大陆上的每一个点,有水向海拔=<自己的方向流动,求既能流进太平洋,又能流进大西洋的坐标位置。

    Example:
    
    Given the following 5x5 matrix:
    
      Pacific ~   ~   ~   ~   ~ 
           ~  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  *
              *   *   *   *   * Atlantic
    
    Return:
    
    [[0, 4], [1, 3], [1, 4], [2, 2], [3, 0], [3, 1], [4, 0]] (positions with parentheses in above matrix).
    
    Note:
    1.The order of returned grid coordinates does not matter.
    2.Both m and n are less than 150.
    

      

    解法:BFS,DFS

    解法一:BFS

    思想:使用两个queue,分别记录:太平洋Pcf_q,大西洋Atl_q

    逆着水流,从沿岸开始,向海拔高的地方进行遍历,当有水流过,则记录水流数组Pcf,Atl对应cell为true。否则为false。

    BFS遍历整个大陆后,

    对比两个水流数组Pcf,Atl

    同样的cell中,都为true,则符合题意。

    代码参考:

     1 class Solution {
     2 public:
     3     int m,n;
     4     void bfs(queue<pair<int,int>>& q, vector<vector<bool>>& visited, vector<vector<int>>& matrix) {
     5         int dir[5] = {1,0,-1,0,1};
     6         int cur_i, cur_j, x, y;
     7         while(!q.empty()) {
     8             int sz = q.size();
     9             for(int i=0; i<sz; i++) {
    10                 cur_i = q.front().first;
    11                 cur_j = q.front().second;
    12                 q.pop();
    13                 for(int j=1; j<5; j++) {
    14                     x = cur_i+dir[j-1];
    15                     y = cur_j+dir[j];
    16                     if(x<0 || x>=n || y<0 || y>=m 
    17                        || visited[x][y] || matrix[x][y]<matrix[cur_i][cur_j]) continue;
    18                     q.push({x,y});
    19                     visited[x][y]=true;
    20                 }
    21             }
    22         }
    23         return;
    24     }
    25     vector<vector<int>> pacificAtlantic(vector<vector<int>>& matrix) {
    26         vector<vector<int>> res;
    27         queue<pair<int,int>> Pcf_q, Atl_q;
    28         n = matrix.size();
    29         if(n==0) return res;
    30         m = matrix[0].size();
    31         vector<vector<bool>> Pcf(n,vector<bool>(m,false));
    32         vector<vector<bool>> Atl(Pcf);//visited
    33         //add board to queue
    34         for(int i=0; i<n; i++) {
    35             Pcf_q.push({i,0});//left
    36             Pcf[i][0] = true;
    37             Atl_q.push({i,m-1});//right
    38             Atl[i][m-1] = true;
    39         }
    40         for(int j=0; j<m; j++) {
    41             Pcf_q.push({0,j});//up
    42             Pcf[0][j] = true;
    43             Atl_q.push({n-1,j});//bottom
    44             Atl[n-1][j] = true;
    45         }
    46         bfs(Pcf_q, Pcf, matrix);
    47         bfs(Atl_q, Atl, matrix);
    48         for(int i=0; i<n; i++) {
    49             for(int j=0; j<m; j++) {
    50                 if(Pcf[i][j] && Atl[i][j]) res.push_back({i,j});
    51             }
    52         }
    53         return res;
    54     }
    55 };

    解法二:DFS

    思想:

    逆着水流,从沿岸开始,向海拔高的地方进行遍历,

    • 从左边+上边所有边缘点开始,向大陆内部DFS遍历,所遍历过满足条件的cell,都是可以流入Pcf太平洋的。
    • 从右边+下边所有边缘点开始,向大陆内部DFS遍历,所遍历过满足条件的cell,都是可以流入Atl大西洋的。

    DFS:

    • 状态:到当前点(i , j)为止,水流都可流过,到达Pcf或Atl
    • 选择:四个方向:dir={{0,1},{1,0},{0,-1},{-1,0}},其中满足:除去非法:
      • 超出边缘x<0 || x>=n || y<0 || y>=m
      • or 访问过 visited[x][y] == true
      • or 海拔低于当前点:matrix[x][y]<matrix[i][j]
    • 递归退出:在以上选择的时候,最终无可选择即可退出。因此无需多加一步递归退出判断。

    当有水流过,则记录水流数组Pcf,Atl对应cell为true。否则为false。

    BFS遍历整个大陆后,

    对比两个水流数组Pcf,Atl

    同样的cell中,都为true,则符合题意。

    代码参考:

     1 class Solution {
     2 public:
     3     int m,n;
     4     void dfs(vector<vector<bool>>& visited, int i, int j, vector<vector<int>>& matrix) {
     5         int dir[5] = {1,0,-1,0,1};
     6         int x, y;
     7         visited[i][j] = true;
     8         for(int d=1; d<5; d++) {
     9             x = i+dir[d-1];
    10             y = j+dir[d];
    11             if(x<0 || x>=n || y<0 || y>=m 
    12             || visited[x][y] || matrix[x][y]<matrix[i][j]) continue;
    13             dfs(visited, x, y, matrix);
    14         }
    15         return;
    16     }
    17     vector<vector<int>> pacificAtlantic(vector<vector<int>>& matrix) {
    18         vector<vector<int>> res;
    19         n = matrix.size();
    20         if(n==0) return res;
    21         m = matrix[0].size();
    22         vector<vector<bool>> Pcf(n,vector<bool>(m,false));
    23         vector<vector<bool>> Atl(Pcf);//visited
    24         //Start DFS from board:
    25         for(int i=0; i<n; i++) {
    26             dfs(Pcf, i, 0, matrix);//left
    27             dfs(Atl, i, m-1, matrix);//right
    28         }
    29         for(int j=0; j<m; j++) {
    30             dfs(Pcf, 0, j, matrix);//up
    31             dfs(Atl, n-1, j, matrix);//bottom
    32         }
    33         for(int i=0; i<n; i++) {
    34             for(int j=0; j<m; j++) {
    35                 if(Pcf[i][j] && Atl[i][j]) res.push_back({i,j});
    36             }
    37         }
    38         return res;
    39     }
    40 };
  • 相关阅读:
    获取Android状态栏高度的屡试不爽的方法
    在线音乐API的研究 (Part 2.1)
    Zabbix
    利用 Puppet 实现自动化管理配置 Linux 计算机集群
    django的admin后台管理如何更改为中文
    windows系统安装python3.6.3和python3.7.0
    微课程--Android--高级控件之二--标题栏
    微课程--Android--高级控件之一ListView
    微课程--Android--Fragement
    微课程--Android--界面布局总结
  • 原文地址:https://www.cnblogs.com/habibah-chang/p/14470015.html
Copyright © 2020-2023  润新知