设置两个数组,记录当前节点是否能够能流向太平洋和大西洋,从边界开始扩展, 能够扩展到的结点表示该节点能够流向太平洋或者大西洋,最后两个数组标志都1的坐标结点即为正确答案。
class Solution {
public:
int tp[155][155];
int dx[155][155];
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
vector<vector<int> >ans;
void dfs(vector<vector<int>>& matrix,int vis[][155],int x,int y){
vis[x][y]=1;
for(int i=0;i<4;i++){
int xx=x+dir[i][0];
int yy=y+dir[i][1];
if(xx<0||xx>=matrix.size()||yy<0||yy>=matrix[0].size()||vis[xx][yy])
continue;
if(matrix[x][y]<=matrix[xx][yy])
dfs(matrix,vis,xx,yy);
}
}
vector<vector<int>> pacificAtlantic(vector<vector<int>>& matrix) {
int r=matrix.size();
if(r==0)
return {};
int c=matrix[0].size();
for(int i=0;i<r;i++){
dfs(matrix,dx,i,c-1);
dfs(matrix,tp,i,0);
}
for(int j=0;j<c;j++){
dfs(matrix,tp,0,j);
dfs(matrix,dx,r-1,j);
}
for(int i=0;i<r;i++)
for(int j=0;j<c;j++)
if(tp[i][j]&&dx[i][j])
ans.push_back({i,j});
return ans;
}
};
我原来是这么做的,从任一结点出发,如果这个节点能够扩展到边界,说明这个节点到边界上的路径都可以到达这个边界,所以可以采用记忆化搜索。
但是这样有一个问题,在每次从一个结点开始扩展时,都必须初始化vis数组,因为有这样一种情况:若不初始化vis数组,A能够流向B再流向边界,但是C跟A的高度等高,A流向C后发现从C不能流向边界,但在下一次搜索时,C的vis已经访问过了,所以会直接返回C不能流向边界的结果,但其实C是能够流向A再流向边界的。这样做的效率不如上面这种高。
下图是两种方法的时间对比:
代码:
class Solution {
public:
int tp[155][155];
int dx[155][155];
int f[155][155];
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
int row,col;
int vis[155][155];
vector<vector<int> > ans;
pair<bool,bool> dfs(int r,int c,vector<vector<int>>& m){
if(vis[r][c]){
return pair<bool,bool>(tp[r][c],dx[r][c]);
}
vis[r][c]=1;
if(r==0||c==0)
tp[r][c]=1;
if(r==row-1||c==col-1)
dx[r][c]=1;
for(int i=0;i<4;i++){
int rr=r+dir[i][0];
int cc=c+dir[i][1];
if(rr<0||rr>row-1||cc<0||cc>col-1||m[rr][cc]>m[r][c])
continue;
pair<bool,bool> p;
if(vis[rr][cc])
p= make_pair(tp[rr][cc],dx[rr][cc]);
else
p=dfs(rr,cc,m);
tp[r][c]=tp[r][c]||p.first;
dx[r][c]=dx[r][c]||p.second;
}
f[r][c]=tp[r][c]&&dx[r][c];
return pair<bool,bool>(tp[r][c],dx[r][c]);
}
vector<vector<int> > pacificAtlantic(vector<vector<int>>& matrix) {
if(matrix.size()==0)
return {};
row=matrix.size();
col=matrix[0].size();
memset(f,-1,sizeof f);
for(int i=0;i<row;i++)
for(int j=0;j<col;j++){
if(tp[i][j]&&dx[i][j]){
ans.push_back({i,j});
continue;
}
memset(vis,0,sizeof vis);
pair<bool,bool>p=dfs(i,j,matrix);
if(p.first&&p.second){
ans.push_back({i,j});
}
}
return ans;
}
};