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