JAVA 17ms Solution, Simple and Clear, similar to Number of Islands's idea
The idea is as following:\n\nFirst, we can separate Pacific and Atlantic ocean into two, they share the same idea. The only difference is the starting position.
The idea is as following:\n\nFirst, we can separate Pacific and Atlantic ocean into two, they share the same idea. The only difference is the starting position.\n\nSecond, we think this problem in the opposite way: all the valid positions must have at least one path to connect to the ocean, so we start from the ocean to find out all the paths.\n\n1, 1, 1, 1\n1, 0, 0, 0\n1, 0, 0, 0\n1, 0, 0, 0\n\nThen we create a new boolean[][] matrix like above, all the beaches is marked as True (1) in the beginning, which means they can connect to the ocean, then we explore from the beach to find out all the paths. The idea is the same for Pacific and Atlantic.\n\nThe last step is to use && to find positions satisfy both Pacific and Atlantic.\n\nHere comes the solution:\n\n\n\n    static int[] dx = {-1,0,0,1};\n    static int[] dy = {0,1,-1,0};\n    public List<int[]> pacificAtlantic(int[][] matrix) {\n        List<int[]> res = new ArrayList<>();\n        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) return res;\n        boolean[][] pacific = new boolean[matrix.length][matrix[0].length];\n        boolean[][] atlantic = new boolean[matrix.length][matrix[0].length];\n        for (int i = 0; i < matrix.length; i++){\n            pacific[i][0] = true;\n            atlantic[i][matrix[0].length-1] = true;\n        }\n        for (int j = 0; j < matrix[0].length; j++){\n            pacific[0][j] = true;\n            atlantic[matrix.length-1][j] = true;\n        }\n        for (int i = 0; i < matrix.length; i++){\n            explore(pacific, matrix, i, 0);\n            explore(atlantic, matrix, i, matrix[0].length-1);\n        }\n        for (int j = 0; j < matrix[0].length; j++){\n            explore(pacific, matrix, 0, j);\n            explore(atlantic, matrix, matrix.length-1, j);\n        }\n        for (int i = 0; i < matrix.length; i++){\n            for (int j = 0; j < matrix[0].length; j++){\n                if (pacific[i][j] && atlantic[i][j] == true)\n                    res.add(new int[]{i,j});\n            }\n        }\n        return res;\n        \n    }\n    private void explore(boolean[][] grid, int[][] matrix, int i, int j){\n        grid[i][j] = true;\n        for (int d = 0; d < dx.length; d++){\n            if (i+dy[d] < grid.length && i+dy[d] >= 0 && \n                j + dx[d] < grid[0].length && j + dx[d] >= 0 && \n                grid[i+dy[d]][j+dx[d]] == false && matrix[i+dy[d]][j+dx[d]] >= matrix[i][j])\n                    explore(grid, matrix, i+dy[d], j+dx[d]);\n        }\n    }
[]