def pacific_atlantic(heights):
m,n=len(heights),len(heights[0])
pac,atl=set(),set()
def dfs(r,c,visited,prev):
if (r,c) in visited or r<0 or r>=m or c<0 or c>=n or heights[r][c]<prev: return
visited.add((r,c))
for dr,dc in [(1,0),(-1,0),(0,1),(0,-1)]:
dfs(r+dr,c+dc,visited,heights[r][c])
for r in range(m): dfs(r,0,pac,heights[r][0]); dfs(r,n-1,atl,heights[r][n-1])
for c in range(n): dfs(0,c,pac,heights[0][c]); dfs(m-1,c,atl,heights[m-1][c])
return [[r,c] for r in range(m) for c in range(n) if (r,c) in pac and (r,c) in atl]
public List<List<Integer>> pacificAtlantic(int[][] heights){
int m=heights.length,n=heights[0].length;
boolean[][] pac=new boolean[m][n],atl=new boolean[m][n];
for(int r=0;r<m;r++){dfs(heights,pac,r,0,0);dfs(heights,atl,r,n-1,0);}
for(int c=0;c<n;c++){dfs(heights,pac,0,c,0);dfs(heights,atl,m-1,c,0);}
List<List<Integer>> res=new ArrayList<>();
for(int r=0;r<m;r++) for(int c=0;c<n;c++)
if(pac[r][c]&&atl[r][c]) res.add(Arrays.asList(r,c));
return res;
}
void dfs(int[][] h,boolean[][] vis,int r,int c,int prev){
if(r<0||r>=h.length||c<0||c>=h[0].length||vis[r][c]||h[r][c]<prev) return;
vis[r][c]=true;
for(int[] d:new int[][]{{1,0},{-1,0},{0,1},{0,-1}}) dfs(h,vis,r+d[0],c+d[1],h[r][c]);
}
Reverse DFS from borders. Python set of tuples vs Java boolean 2D array.
def pacific_atlantic(heights):
m,n=len(heights),len(heights[0])
pac,atl=set(),set()
def dfs(r,c,visited,prev):
if (r,c) in visited or r<0 or r>=m or c<0 or c>=n or heights[r][c]<prev: return
visited.add((r,c))
for dr,dc in [(1,0),(-1,0),(0,1),(0,-1)]:
dfs(r+dr,c+dc,visited,heights[r][c])
for r in range(m): dfs(r,0,pac,heights[r][0]); dfs(r,n-1,atl,heights[r][n-1])
for c in range(n): dfs(0,c,pac,heights[0][c]); dfs(m-1,c,atl,heights[m-1][c])
return [[r,c] for r in range(m) for c in range(n) if (r,c) in pac and (r,c) in atl]
public List<List<Integer>> pacificAtlantic(int[][] heights){
int m=heights.length,n=heights[0].length;
boolean[][] pac=new boolean[m][n],atl=new boolean[m][n];
for(int r=0;r<m;r++){dfs(heights,pac,r,0,0);dfs(heights,atl,r,n-1,0);}
for(int c=0;c<n;c++){dfs(heights,pac,0,c,0);dfs(heights,atl,m-1,c,0);}
List<List<Integer>> res=new ArrayList<>();
for(int r=0;r<m;r++) for(int c=0;c<n;c++)
if(pac[r][c]&&atl[r][c]) res.add(Arrays.asList(r,c));
return res;
}
void dfs(int[][] h,boolean[][] vis,int r,int c,int prev){
if(r<0||r>=h.length||c<0||c>=h[0].length||vis[r][c]||h[r][c]<prev) return;
vis[r][c]=true;
for(int[] d:new int[][]{{1,0},{-1,0},{0,1},{0,-1}}) dfs(h,vis,r+d[0],c+d[1],h[r][c]);
}
1. DFS from each border 2. Find cells reachable from both