Dada una m x n
matriz de enteros no negativos que representa la altura de cada celda unitaria en un continente, el "océano Pacífico" toca los bordes izquierdo y superior de la matriz y el "océano Atlántico" toca los bordes derecho e inferior.
El agua solo puede fluir en cuatro direcciones (arriba, abajo, izquierda o derecha) de una celda a otra con una altura igual o menor.
Encuentre la lista de coordenadas de la cuadrícula donde el agua puede fluir hacia el océano Pacífico y el Atlántico.
Nota:
- El orden de las coordenadas de cuadrícula devueltas no importa.
- Tanto m y n son de menos de 150.
Ejemplo:
Dada la siguiente matriz 5x5: Pacífico ~ ~ ~ ~ ~ ~ 1 2 2 3 (5) * ~ 3 2 3 (4) (4) * ~ 2 4 (5) 3 1 * ~ (6) (7) 1 4 5 * ~ (5) 1 1 2 4 * * * * * * Atlantic Return: [[0, 4], [1, 3], [1, 4], [2, 2], [3, 0], [3, 1], [4, 0]] (posiciones con paréntesis en la matriz anterior).
Idea: Use dos matrices booleanas para indicar que el agua está yendo hacia adentro y va a terreno alto para ver dónde puede fluir, lo que puede reducir el cálculo; al mismo tiempo, el lugar donde coinciden las dos últimas matrices es el punto de superposición que puede fluir a ambos lados;
class Solution {
public List<List<Integer>> pacificAtlantic(int[][] matrix) {
List<List<Integer>> lists = new ArrayList<List<Integer>>();
if(matrix == null || matrix.length == 0 || matrix[0].length == 0) {
return lists;
}
int n = matrix.length;
int m = matrix[0].length;
boolean[][] visitp = new boolean[n][m];
boolean[][] visita = new boolean[n][m];
Queue<int[]> pqueue = new LinkedList<int[]>();
Queue<int[]> aqueue = new LinkedList<int[]>();
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
if(i == 0 || j == 0) {
pqueue.offer(new int[]{i, j});
visitp[i][j] = true;
}
if(i == n - 1 || j == m - 1) {
aqueue.offer(new int[]{i, j});
visita[i][j] = true;
}
}
}
bfs(pqueue, matrix, visitp);
bfs(aqueue, matrix, visita);
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
if(visitp[i][j] && visita[i][j]) {
List<Integer> list = new ArrayList<Integer>();
list.add(i);
list.add(j);
lists.add(list);
}
}
}
return lists;
}
private void bfs(Queue<int[]> queue, int[][] matrix, boolean[][] visited) {
int[] dx = {0,0,-1,1};
int[] dy = {-1,1,0,0};
int n = matrix.length;
int m = matrix[0].length;
while(!queue.isEmpty()) {
int[] head = queue.poll();
int headx = head[0];
int heady = head[1];
visited[headx][heady] = true;
for(int k = 0; k < 4; k++) {
int nx = headx + dx[k];
int ny = heady + dy[k];
if(0 <= nx && nx < n && 0 <= ny && ny < m
&& !visited[nx][ny] && matrix[nx][ny] >= matrix[headx][heady]) {
visited[nx][ny] = true;
queue.offer(new int[]{nx, ny});
}
}
}
}
}