Given an m x n matrix of non-negative integers representing the height of each unit cell in a continent, the "Pacific ocean" touches the left and top edges of the matrix and the "Atlantic ocean" touches the right and bottom edges. Water can only flow in four directions (up, down, left, or right) from a cell to another one with height equal or lower.
Find the list of grid coordinates where water can flow to both the Pacific and Atlantic ocean. Note: The order of returned grid coordinates does not matter. Both m and n are less than 150.less
Time Complexity
O(mn)
Space Complexity
O(mn)this
Add all boundary of Pacific ocean into queue. Do bfs and then reuse the same queue, if this point hasn't been visited and the value is bigger or equal to the current point value, then put it into queue and make it visited. Put all Atlantic ocean boundary into queue do the same bfs. We can't add one point to the queue twice, it will cause duplicate. If the point can be touched from Pacific ocean, add it into pac, if the point can be touched from Atlantic ocean, add it into alt. If one point is both in pac and alt, add it to res.code
public List<int[]> pacificAtlantic(int[][] matrix) { List<int[]> res = new ArrayList<int[]>(); if(matrix == null || matrix.length == 0 || matrix[0] == null || matrix[0].length == 0) return res; int rows = matrix.length, cols = matrix[0].length; int[][] directions = new int[][]{{-1, 0},{1, 0},{0, -1},{0,1}}; boolean[][] pac = new boolean[rows][cols]; boolean[][] alt = new boolean[rows][cols]; Queue<int[]> queue = new LinkedList<int[]>(); //add Pacific on left for(int i = 0; i < rows; i++){ queue.offer(new int[]{i,0}); pac[i][0] = true; } //add Pacific on top for(int j = 1; j < cols; j++){ queue.offer(new int[]{0,j}); pac[0][j] = true; } bfs(matrix, rows, cols, queue, pac, alt, directions, res); //add Atlantic on bottom for(int j = 0; j < cols - 1; j++){ queue.offer(new int[]{rows - 1, j}); alt[rows - 1][j] = true; } //add Atlantic on right for(int i = 0; i < rows; i++){ queue.offer(new int[]{i, cols - 1}); alt[i][cols - 1] = true; } bfs(matrix, rows, cols, queue, alt, pac, directions, res); return res; } private void bfs(int[][] matrix, int rows, int cols, Queue<int[]> queue, boolean[][] self, boolean[][] others, int[][] directions, List<int[]> res){ while(!queue.isEmpty()){ int[] cur = queue.poll(); if(others[cur[0]][cur[1]]) res.add(new int[]{cur[0],cur[1]}); for(int[] dir : directions){ int x = cur[0] + dir[0]; int y = cur[1] + dir[1]; if(x >= 0 && x < rows && y >= 0 && y < cols && self[x][y] == false && matrix[x][y] >= matrix[cur[0]][cur[1]]){ self[x][y] = true; queue.offer(new int[]{x,y}); } } } }