Leetcode: Pacific Atlantic Water Flow

417. Pacific Atlantic Water Flow

题意大概是说输入2维 int 矩阵,数值表示高度,规定水只能朝上下左右四个方向流,输出同时满足1、能够流到矩阵的上边缘或者左边缘;2、能够流到矩阵的下边缘或者右边缘的所有坐标点。

简单分析之后觉得这是一道 dp 题,写的飞起,一个 dp 表从左上角开始更新满足条件1的点,只需要检查能流到左边(或上边)且左边(或上边)满足1则该点也更新;另一个 dp 表从右下角开始更新满足条件2的点,最后遍历一遍2张表找出同时都满足的入队输出。

显然我2b了,这个玩意儿是可以上下左右流的。。。比如

1 2 3

8 9 4

7 6 5

值6的点可以直接流到下边,同时可以通过6->5->4->3流到上边!!

好,那没办法了,dp 一遍过下来肯定是没戏的,只能 dfs 了,还是两个条件两个表,但是思路换成这样:左边和上边第一排满足条件1,那么从其中的每个点向4个方向开始深搜,注意检查是否越界和流向规则成立。四个方向写成数组,用循环减少重复省代码量;还有如果已经满足了就不要搜了,否则会在里面死循环的哈。注意这几点很快就 ac 啦,而且效率很高。

 1 class Solution {
 2 public:
 3     int d[4][2] = {{0, -1}, {-1, 0}, {1, 0}, {0, 1}};
 4     int m, n;
 5     
 6     void dfs(vector<vector<int>>& matrix, vector<vector<int>>& dp, int x, int y) {
 7         if (dp[x][y] == 1) return;
 8         dp[x][y] = 1;
 9         for (int k=0;k<4;++k) {
10             int _x = x+d[k][0];
11             int _y = y+d[k][1];
12             if ( _x>=0 && _x<m && _y>=0 && _y<n ) {
13                 if (matrix[_x][_y] >= matrix[x][y]) {
14                     dfs(matrix, dp, _x, _y);
15                 }
16             }
17         }
18         return;
19     }
20     
21     vector<pair<int, int>> pacificAtlantic(vector<vector<int>>& matrix) {
22         vector<pair<int, int>> res;
23         m = matrix.size();
24         if (m == 0) return res;
25         n = matrix[0].size();
26         if (n == 0) return res;
27         
28         vector<vector<int> > dp_Pac(m, vector<int>(n, 0));
29         for (int i=0;i<m;++i) dfs(matrix, dp_Pac, i, 0);
30         for (int j=0;j<n;++j) dfs(matrix, dp_Pac, 0, j);
31 
32         
33         vector<vector<int> > dp_Atl(m, vector<int>(n, 0));
34         for (int i=0;i<m;++i) dfs(matrix, dp_Atl, i, n-1);
35         for (int j=0;j<n;++j) dfs(matrix, dp_Atl, m-1, j);
36 
37         
38         for (int i=0;i<m;++i) {
39             for (int j=0;j<n;++j) {
40                 if (dp_Pac[i][j] == 1 && dp_Atl[i][j] == 1) {
41                     res.push_back(pair<int, int>(i, j));
42                 }
43             }
44         }
45         return res;
46     }
47 };

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值