[Práctica diaria] - algoritmo de búsqueda en anchura (BFS)

título Descripción

Ahora tiene una mano de tamaño N x "mapa" de rejilla (rejilla) de N, por encima de cada "zona" (células) son etiquetados con 0 y 1 también. Donde 0 representa el océano, 1 en nombre de la tierra, ya sabes áreas marinas más alejado de áreas de tierra de cuál se trata? Por favor, devuelva el área al mar desde las zonas de tierra más próxima.
Estamos hablando aquí de la distancia "a distancia de Manhattan" (distancia Manhattan) :( x0, y0 ) y (x1, y1) la distancia entre las dos regiones es | x0 - x1 | + | y0 - y1 |.
El título proviene del leetcode, haga clic para entrar

Leer título

Ejemplo:

1 0 1
0 0 0
1 0 1

Entrada: [[1,0,1], [0,0,0], [1,0,1]]
de salida: 2
Explicación:
la distancia entre la zona de mar (1, 1) y el máximo de todas las zonas terrestres una distancia máxima de 2.
2 ¿Por qué es el resultado? La fórmula se puede derivar de la adición de la célula intermedia (1,1), el otro de la célula más cercana de células son de 0 a 1, por lo que (1,1) es el punto Necesitamos encontrar.

Violenta resolución de problemas

Aquí el primer periodo del código violentos de resolución de problemas, aunque esto también puede obtener la respuesta correcta, pero la eficiencia es muy baja.

public static int maxDistance(int[][] grid) {
        // 距离陆地区域最远的海洋区域到离它最近的陆地区域的距离
        int minDistance = 0;
        // 将所有海洋和陆地的坐标分别存储
        List<int[]> listLand = new ArrayList<int[]>();
        List<int[]> ListOcean = new ArrayList<int[]>();
        for (int i = 0; i <grid.length ; i++) {
            for (int j = 0; j <grid[i].length ; j++) {
                if(grid[i][j]==0){
                    ListOcean.add(new int[]{i,j});
                }else{
                    listLand.add(new int[]{i,j});
                }
            }
        }
        // 如果全部都是海洋或者陆地直接返回-1
        if(listLand.size()==0 || ListOcean.size()==0){
            return -1;
        }

        for (int i = 0; i < ListOcean.size(); i++) {
            int curMinDistance = 0; // 当前循环海洋区域距离其他陆地区域最近的距离
            for (int j = 0; j < listLand.size(); j++) {
                // 每个陆地与改海洋点位的距离
                int distance = Math.abs(listLand.get(j)[0]-ListOcean.get(i)[0]) + Math.abs(listLand.get(j)[1]-ListOcean.get(i)[1]);
                // 如果该海洋距离陆地的点位的距离比其他已比较的点位的最小距离还小  则修改距离陆地的最近距离为该距离
                // 首次循环直接赋值
                curMinDistance = curMinDistance == 0 ? distance : distance < curMinDistance ? distance : curMinDistance;
            }
            // 如果该海洋点位与其所有陆地的最小距离比其他海洋点位与所有陆地点位的距离还要小,则认为当前点位为距离陆地区域最远的海洋区域
            if(minDistance < curMinDistance){
                minDistance = curMinDistance;
            }
        }
        return minDistance;
    }

BFS resolución de problemas

Vamos a ver el punto de todo el área de la tierra y luego se extienden hacia el exterior buscando, inundaron cada paso de tiempo, luego se extendió al último punto es el punto más lejano que tenemos que encontrar. Tal descripción puede ser un poco abstracto, siguiendo un conjunto de imágenes para ilustrar. Luego se recorre capas, cada punto con el tiempo de recorrido completarse en este momento es el último punto que tenemos que llegar a un punto.
Aquí Insertar imagen Descripción

código

public static int maxDistance(int[][] grid) {
        // 对应当前坐标周围的四个坐标
        int[] aroundX = {0,0,1,-1};
        int[] aroundY = {1,-1,0,0};
        // 记录所有陆地区域的点
        Queue<int[]> queueLand = new ArrayDeque<int[]>();
        int colLength = grid.length;
        int rowLength = grid[0].length; // 因为grid中每个元素的长度都相同,这里取第一个
        for (int i = 0; i < colLength; i++) {
            for (int j = 0; j < rowLength; j++) {
                if(grid[i][j] == 1){
                    queueLand.offer(new int[]{i,j});
                }
            }
        }

        // 循环各个陆地 向外扩散 这里运用队列先进先出的特性
        boolean isAllLandOrOcean = false;
        int[] maxPoint = null;
        while (!queueLand.isEmpty()){
            maxPoint = queueLand.poll(); // 取出第一个点位的值并从队列中删除
            // 遍历周围的四个点 以当前区域对X,Y坐标进行增减可得到周围的四个点
            for (int i = 0; i < 4 ; i++) {
                int newX = maxPoint[0] + aroundX[i];
                int newY = maxPoint[1] + aroundY[i];
                // 只对海洋区域的点位操作
                if(newX > -1 &&  newX < colLength && newY > -1 && newY < rowLength && grid[newX][newY] == 0){
                    isAllLandOrOcean = true; // 能进入这里说明队列肯定不为空且存在未海洋区域的点
                    // 修改海洋区域的点位为距离最近的陆地的距离 从陆地点位向外扩散 每次以当前节点的值+1
                    grid[newX][newY] = grid[maxPoint[0]][maxPoint[1]] + 1;
                    // 把点位加到队列中进行下一轮循环
                    queueLand.offer(new int[]{newX,newY});
                }
            }
        }
        if(maxPoint == null || ! isAllLandOrOcean){
            return -1;
        }
        return grid[maxPoint[0]][maxPoint[1]] - 1;
    }
Publicado 26 artículos originales · ganado elogios 6 · vistas 2937

Supongo que te gusta

Origin blog.csdn.net/weixin_45676630/article/details/105178167
Recomendado
Clasificación