思路BFS:
对于一个点它能流动两边的大洋,那么反过来,两边大洋的水反着流就能达到这个点。
尽然水开始倒流了,那么逻辑也需要反过来,因此只有将下一个点比当前的点大时或者等于当前点的高度时,水才能流过去。
步骤:
- 找出所有从太平洋出发的水所能达到的点
- 找出所有从大西洋出发的水所能达到的点
- 重合的点便是我们要找的点
class Solution {
public:
//dfs
//反向思维:水往高处流
vector<vector<int>> P,A,R;
int m,n;
vector<vector<int>> pacificAtlantic(vector<vector<int>>& heights) {
//记录行
m=heights.size();
//记录列
n=heights[0].size();
P=A=vector<vector<int>>(m, vector<int>(n, 0));
//深度搜索Pacific Ocean和流向Atlantic Ocean;
for(int i=0;i<n;i++)
{
dfs(heights,P,0,i);
dfs(heights,A,m-1,i);
}
for(int i=0;i<m;i++)
{
dfs(heights,P,i,0);
dfs(heights,A,i,n-1);
}
return R;
}
void dfs(vector<vector<int>>&heights,vector<vector<int>>& visit,int x,int y)
{
if(visit[x][y]) return ;
visit[x][y]=1;
if(A[x][y]&&P[x][y])
{
R.push_back({x,y});
}
//向下搜索
if(x-1>=0&&heights[x][y]<=heights[x-1][y]) dfs(heights,visit,x-1,y);
if(x+1<m&&heights[x][y]<=heights[x+1][y]) dfs(heights,visit,x+1,y);
if(y-1>=0&&heights[x][y]<=heights[x][y-1]) dfs(heights,visit,x,y-1);
if(y+1<n&&heights[x][y]<=heights[x][y+1]) dfs(heights,visit,x,y+1);
}
};
class Solution:
def pacificAtlantic(self, heights: List[List[int]]) -> List[List[int]]:
m,n=len(heights),len(heights[0])
p=[[False for _ in range(n)] for _ in range(m)]
a=[[False for _ in range(n)] for _ in range(m)]
h=heights
def dfs_a(x,y):
#因为是从边界开始访问的,边界一定是可以流入的,所以先置为True
a[x][y]=True
#搜索上下左右四个点
for nx,ny in [(x+1,y),(x-1,y),(x,y-1),(x,y+1)]:
#如果范围不越界,没有遍历过,比较可以流向,就进一步搜索
if 0<=nx<m and 0<=ny<n and not a[nx][ny] and h[nx][ny]>=h[x][y]:
dfs_a(nx,ny)
def dfs_p(x,y):
#因为是从边界开始访问的,边界一定是可以流入的,所以先置为True
p[x][y]=True
#搜索上下左右四个点
for nx,ny in [(x+1,y),(x-1,y),(x,y-1),(x,y+1)]:
#如果范围不越界,没有遍历过,比较可以流向,就进一步搜索
if 0<=nx<m and 0<=ny<n and not p[nx][ny] and h[nx][ny]>=h[x][y]:
dfs_p(nx,ny)
for i in range(m):
dfs_a(i,n-1)
dfs_p(i,0)
for j in range(n):
dfs_a(m-1,j)
dfs_p(0,j)
res=[]
for i in range(m):
for j in range(n):
if a[i][j] and p[i][j]:
res.append([i,j])
return res