417. Pacific Atlantic Water Flow

T: O(4*mn + mn)

S: O(2*mn)

class Solution {
    int[][] dirs = {{0,1}, {1,0}, {0,-1}, {-1,0}};
    public List<List<Integer>> pacificAtlantic(int[][] heights) {
        List<List<Integer>> res = new ArrayList<>();
        
        int m = heights.length;
        int n = heights[0].length;
        boolean pacific[][] = new boolean[m][n];
        boolean atlantic[][] = new boolean[m][n];

        for (int j = 0; j < n; j++) {
            pacific[0][j] = true;
            dfs(heights, 0, j, pacific);
            
            atlantic[m-1][j] = true;
            dfs(heights, m-1, j, atlantic);
        }
        for (int i = 0; i < m; i++) {
            pacific[i][0] = true;
            dfs(heights, i, 0, pacific);
            
            atlantic[i][n-1] = true;
            dfs(heights, i, n-1, atlantic);
        }
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (pacific[i][j] && atlantic[i][j]) {
                    res.add(Arrays.asList(i, j));
                }
            }
        }
        return res;
        
    }
    private void dfs(int[][] heights, int i, int j, boolean visited[][]) {
        for (int[] dir : dirs) {
            int x = i + dir[0];
            int y = j + dir[1];
            
            if (!inArea(heights, x, y) || visited[x][y] || heights[i][j] > heights[x][y]) { // new should higer than before
                continue;
            }
            visited[x][y] = true;
            dfs(heights, x, y, visited);
        }
    }
    private boolean inArea(int[][] heights, int i, int j) {
        return i >= 0 && i < heights.length && j >= 0 && j < heights[0].length;
    }
}

/*
Pacific Ocean touches the island's left and top edges
and the Atlantic Ocean touches the island's right and bottom edges.

heights[r][c]

water flow:
curr cell height >= neightbor height

    P

P       A
    A

return result[i] = [ri, ci] => [[ri, ci],[ri, ci],[ri, ci]...]
rain water can flow from cell (ri, ci) to 
both the Pacific and Atlantic oceans.


water flow: 思路是從低處到高處做, 水往高處流...反正能相通兩邊就好了
curr cell height >= neightbor height => 
如果從邊邊出發, 這條件就要相反 => curr cell height <= neightbor

反過來就是 curr cell height > neightbor, 不繼續

Pacific
dfs from i = 0, j = 0~n-1
dfs from i = 0~m-1, j = 0
if (water can arrive, Pacific[i][j] = true)

Atlantic
dfs from i = m-1, j = 0~n-1
dfs from i = 0~m-1, j = n-1
if (water can arrive, Atlantic[i][j] = true)


at last for (i 0~m)
          for (j 0~n)
        if water both can arrive, put to res[]
        

ps.
对于一个点它能流动两边的大洋,那么反过来,两边大洋的水反着流就能达到这个点。
尽然水开始倒流了,那么逻辑也需要反过来,因此只有将下一个点比当前的点大时或者等于当前点的高度时,水才能流过去。


*/

Last updated