[Pregunta diaria] DFS con restricciones: escape del laberinto, reanude la actualización hoy

1036. Escape del laberinto\color{red}{1036. Escape del laberinto}1 0 3 6 .Escape del gran laberinto

En una cuadrícula de 10^6 x 10^6, las coordenadas de cada celda de la cuadrícula son (x, y).

Ahora source = [sx, sy], comenzando desde el cuadro de origen, la intención es correr hacia el cuadro de destino target = [tx, ty]. La matriz blockedes una lista de cuadrados bloqueados, cada uno de los cuales blocked[i] = [xi, yi]indica que (xi, yi)el cuadrado con coordenadas tiene prohibido pasar.

Cada vez que te mueves, puedes ir a los cuadrados adyacentes en la cuadrícula en cuatro direcciones, siempre que el cuadrado no esté en la lista de bloques dada blocked. Al mismo tiempo, no se permite salir de la parrilla.

Solo regrese si es posible llegar desde el cuadro de origen sourceal cuadro de destino mediante una secuencia de movimientos . De lo contrario, regresa .targettruefalse

Restricciones de datos (clave):

  • 0 <= blocked.length <= 200

Ideas para resolver problemas:

  1. En primer lugar, para el problema de encontrar un camino en este tipo de cuadrícula, generalmente se resuelve mediante un algoritmo de búsqueda que selecciona DFS o BFS, y otros algoritmos de búsqueda mejores según si se requiere el camino más corto, el tamaño de los datos , etc.
  2. Debido a la cantidad de datos en esta pregunta, y no hay ningún requisito para encontrar la ruta de "escape" más corta, si se expande gradualmente a través de BFS, definitivamente no tendrá ninguna posibilidad; considere DFS. De acuerdo con la dificultad Difícil de esta pregunta, no es difícil pensar en usar un algoritmo DFS optimizado: la optimización más común es la optimización de poda (hay tres estrategias de poda de uso común: memorización: el mismo valor extrae el resultado de la matriz de memoria, juicio de solución óptima: si la rama actual es peor que la poda óptima actual, poda de factibilidad: la rama actual no se puede despojar)
  3. Pero esta pregunta no debería ser una poda, sino una búsqueda DFS limitada por la distancia: debido a una restricción de datos especial, la cuadrícula bloqueada tiene solo 200 cuadrículas como máximo, suponiendo que estas cuadrículas estén ordenadas por barras para lograr el mejor efecto de bloqueo, similar a lo siguiente, siempre que la distancia de Manhattan entre el punto alcanzado por DFS y el origen alcance cierto rango, es decir, se debe romper el bloqueo. Este rango no es difícil de obtener como longitud bloqueada según el mejor efecto de bloqueo (Figura 1)
  4. Por lo tanto, cuando DFS llega a un punto a cierta distancia del origen, o busca directamente el destino, significa que el nodo está "libre".

Código de resolución de problemas:

Todavía hay mucho margen de mejora:

class Solution {
    
    
    //封锁格子数量
    int len;
    //上下左右方向数组
    int[][] d;
    //保存访问信息
    Map<Integer,Set<Integer>> v;
    //全局block
    int[][] b;

    public boolean isEscapePossible(int[][] blocked, int[] source, int[] target) {
    
    
        b=blocked;
        len=blocked.length;
        d=new int[][]{
    
    {
    
    -1,0},{
    
    1,0},{
    
    0,-1},{
    
    0,1}};

        //访问原节点
        v=new HashMap<>();
        Set<Integer> sou=new HashSet<Integer>();
        sou.add(source[1]);
        v.put(source[0],sou);

        //判断原节点是否free
        if(dfs(source,source,target)){
    
    
            
            
            v=new HashMap<>();
            Set<Integer> tar=new HashSet<Integer>();
            tar.add(target[1]);
            v.put(target[0],tar);

            //判断目标节点是否free
            if(dfs(target,target,source))
                return true;
        }

        return false;
    }

    public boolean dfs(int[] cur,int[] o,int[] t){
    
    
        //如果超过范围,或者到达目标返回true
        if((Math.abs(cur[0]-o[0])+Math.abs(cur[1]-o[1]))>=len||(cur[0]==t[0]&&cur[1]==t[1])){
    
    
            return true;
        }
        else{
    
    
            for(int i=0;i<4;i++){
    
    
                int mx=cur[0]+d[i][0];
                int my=cur[1]+d[i][1];
                if(mx<0||mx>=1000000||my<0||my>=1000000||judge(mx,my)){
    
    
                    continue;
                }
                else{
    
    
                    Set<Integer> j=v.get(mx);
                    if(j==null||!j.contains(my)){
    
    
                        if(j==null){
    
    
                            j=new HashSet<Integer>();
                        }
                        j.add(my);
                        v.put(mx,j);
                        if(dfs(new int[]{
    
    mx,my},o,t))
                            return true;
                    }
                    else{
    
    
                        continue;
                    }
                }
            }
        }
        return false;
    }

    //判断是否是blocked
    public boolean judge(int x,int y){
    
    
        for(int i=0;i<len;i++){
    
    
            if(b[i][0]==x&&b[i][1]==y)
                return true;
        }
        return false;
    }

}

fin

Fuente de la pregunta: Enlace LeetCode: https://leetcode-cn.com/problems

⭐️Siga al autor, llévelo a repasar las preguntas y aprenda las habilidades de algoritmos más utilizadas a partir de preguntas de algoritmos simples (una pregunta por día durante las vacaciones de invierno) ⭐️Siga al autor para
repasar las preguntas, de simple a avanzado, le permite conviértase en una máquina despiadada para eliminar preguntas sin saberlo, si tiene alguna pregunta, envíe un mensaje privado

Supongo que te gusta

Origin blog.csdn.net/caqjeryy/article/details/123507430
Recomendado
Clasificación