题目链接:点击查看
题目描述:
给定一个二维的非负整数矩阵,每个位置的值表示海拔高度。假设左边和上边是太平洋,右边和下边是大西洋,求从哪些位置向下流水,可以流到太平洋和大西洋。水只能从海拔高的位置 流到海拔低或相同的位置。
输入输出:
给定下面的 5x5 矩阵:
太平洋 ~ ~ ~ ~ ~
~ 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 *
* * * * * 大西洋返回:
[[0, 4], [1, 3], [1, 4], [2, 2], [3, 0], [3, 1], [4, 0]] (上图中带括号的单元).
题目分析:
虽然题目要求的是满足向下流能到达两个大洋的位置,如果我们对所有的位置进行搜索,那么在不剪枝的情况下复杂度会很高。因此我们可以反过来想,从两个大洋开始向上流,这样我们只需要对矩形四条边进行搜索。搜索完成后,只需遍历一遍矩阵,满足
条件的位置即为两个大洋向上流都能到达的位置。
代码:
vector<int>direction{-1,0,1,0,-1};
vector<vector<int>>pacificAtlantic(vector<vector<int>>&heights)
{
if(heights.empty()||heights[0].empty())
{
return {};
}
vector<vector<int>>ans;
int m=heights.size(),n=heights[0].size();//用m,n分别表示行和列
vector<vector<bool>>can_reach_p(m,vector<bool>(n,false));
vector<vector<bool>>can_reach_a(m,vector<bool>(n,false));
for(int i=0;i<m;++i)
{
dfs(heights,can_reach_p,i,0);//对矩形的 左 边 进行搜索
dfs(heights,can_reach_a,i,n-1);//对矩形的 右 边 进行搜索
}
for(int i=0;i<n;++i)//因为矩形的左边右边 和 上边下边 每两个的高度(长度)都一样所以要这样分类
{
dfs(heights,can_reach_p,0,i);//对矩形的 顶 边 进行搜索
dfs(heights,can_reach_a,m-1,i);//对矩形 底 边 进行搜索
}
for(int i=0;i<m;++i)
{
for(int j=0;j<n;++j)
{
if(can_reach_p[i][j]&&can_reach_a[i][j])
{
ans.push_back(vector<int>{i,j});
}
}
}
return ans;
}
void dfs(const vector<vector<int>>&heights,vector<vector<bool>>&can_reach,int r,int c)
{
if(can_reach[r][c])//递归出口:访问了已经访问过的点
{
return ;
}
can_reach[r][c]=true;
int x,y;
for(int i=0;i<4;++i)
{
x=r+direction[i],y=c+direction[i+1];
if(x>=0&&x<heights.size()&&y>=0&&y<heights[0].size()&&heights[r][c]<=heights[x][y])//对周围最高海拔进行搜索
{
dfs(heights,can_reach,x,y);
}
}
}