Flujo de agua del Pacífico Atlántico

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:

  1. El orden de las coordenadas de cuadrícula devueltas no importa.
  2. 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});
                }
            }
        }
    }
}

 

710 artículos originales publicados · Me gusta 13 · Visitas 190,000+

Supongo que te gusta

Origin blog.csdn.net/u013325815/article/details/105307098
Recomendado
Clasificación