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 };

 

posted @ 2021-03-02 17:13  habibah_chang  阅读(43)  评论(0编辑  收藏  举报