Algoritmo de búsqueda de retroceso de estructura de datos

1. Problemas que puede resolver el método de búsqueda con retroceso

      (1) Problema de combinación : por ejemplo, hay varias combinaciones de longitud 2 en 1, 2, 3, 4, 12, 13, 14, 23 , 24, 34. No se requiere orden

      (2) Problema de corte : después de hablar sobre cortar una cuerda, asegúrese de que las subcadenas cortadas sean todas palíndromas.

      (3) Problema de subconjunto : por ejemplo, todos los subconjuntos en 1, 2, 3, 4. No se requiere orden

      (4) Problema de disposición : por ejemplo, varias combinaciones de longitud 2 en 1, 2, 3, 4 son 12, 13, 14, 23 , 24, 34, 31, 21, 41, 32, 42 , 43. Necesita orden.

      (4) Problema de tablero de ajedrez : problema de n reina

Es difícil resolver los problemas mencionados anteriormente utilizando bucles, por lo que los problemas mencionados anteriormente deben resolverse mediante el método de retroceso.

2. La idea del método de búsqueda con retroceso

El retroceso se puede abstraer como una estructura de árbol, y el retroceso se puede entender como un bucle for de ancho horizontal y recursividad de profundidad vertical de un árbol.

 3. La rutina general de escribir código (plantilla)

public void backtracking () // define la función de retroceso

{

       // 1, condiciones de rescisión

         if (condición de terminación)

         {

                Recoger resultados;

                regreso ;

         }
 

      // 2, para el nodo de procesamiento de ejecución del bucle, función recursiva, función de retroceso

         para (atravesando elementos de colección)

        {

                Nodo de procesamiento

               función recursiva

               Función de retroceso

        }

        devuelve el resultado final del recorrido.
 

}

4. Aplicación del problema de combinación de algoritmo de retroceso

Primero haga la pregunta, saque todos los conjuntos de longitud 2 en 1, 2, 3 y 4

el código se muestra a continuación:

para (int i = 0 ; i <núm. de longitud; i ++)

{

             para (int j = i; j <longitud num.; j ++)

              {

                    System.out.print (i) ;

                    System.out.print (j) ;
              }
}

Pero si cambiamos la matriz anterior a una combinación de 100 números y una longitud de 50, se necesitan 50 niveles de bucles for para anidar, lo que obviamente no es realista.

En este momento necesitamos realizar un algoritmo de retroceso

Explique esta figura, por qué cada vez que toma un valor, las siguientes ramas no tienen este número, porque la definición de combinación es que la combinación no está en orden, por lo que si no habla de la pérdida de la matriz frontal, inevitablemente hará que los datos se repitan.

Código

Valor de retorno del parámetro de función recursiva

Determinar las condiciones de terminación

Función recursiva de un solo nivel

Código fuente:

List<List<Integer>> result = new ArrayList<List<Integer>>();
List<Integer> path= new ArrayList<Integer>();
List<Integer> path2;
public List<List<Integer>> combine(int n, int k)
{
    backstracking(n,k,1);
    return result;

}
public void  backstracking(int n,int k,int startindex)
{
    if(path.size()==k)
    {
        path2=new ArrayList<Integer>();
        for (int i: path)
        {
            path2.add(i);

        }

        result.add(path2);
        return ;
    }
    for(int i=startindex;i<=n;i++)
    {
        path.add(i);
        backstracking(n,k,i+1);//这里为什么是i+1呢因为不能出现两个字母的重复,如果是i的话就会出现11,22,33这种情况。
        path.remove(path.size()-1);

    }
}

5. Aplicación del problema de la poda del algoritmo de retroceso del problema de combinación

Como se muestra en la siguiente figura: si n = 4 y k = 4, una búsqueda puramente violenta será un gran desperdicio de recursos informáticos, por lo que este algoritmo debe optimizarse para reducir la complejidad de tiempo de este algoritmo.

 Lo principal a cambiar es que el tamaño se cambia a n- (k-path.size) +1;

6. Aplicación de la suma combinada del algoritmo de retroceso

Escenas:

Dada una matriz de candidatos sin elementos repetidos y un objetivo de número objetivo, busque todas las combinaciones de candidatos que pueden hacer el objetivo de suma de números.

El número de candidatos se puede seleccionar repetidamente sin limitación.

Descripción:

Todos los números (incluido el objetivo) son números enteros positivos.
El conjunto de soluciones no puede contener combinaciones repetidas.

Ideas:

Ideas de escritura de código

Valor de retorno del parámetro de función recursiva

Determinar las condiciones de terminación

Función recursiva de un solo nivel

Código fuente:

import java.util.*;
class Solution {
    public List<List<Integer>> combinationSum(int[] candidates, int target) 
    {
        int sum=0;
        int startindex=0;
        backtracking(candidates,target,sum,startindex);
        return result;

    }
    List<List<Integer>> result=new ArrayList<List<Integer>>();
    List<Integer> path =new ArrayList<Integer>();
    List<Integer> path2;
    public void backtracking(int[] candidates, int target,int sum,int startindex)
    {
        //首先确定函数的参数以及返回值
        if(sum>target)
        {
            return ;
        }
        //确定终止条件
        if(sum==target)
        {
            path2=new ArrayList<Integer>(); 
            for(int i: path)
            {
                path2.add(i);
            }
            result.add(path2);
            return;

        }
        //确定单层递归函数
        for(int i=startindex;i<candidates.length;i++)
        {
            path.add(candidates[i]);
            sum=sum+candidates[i];
            backtracking(candidates,target,sum,i);
            sum=sum-candidates[i];
            path.remove(path.size()-1);

        }
        return ;
    }
}

 

 

 

 

 

 

 

 

 

 

 

 

 

Supongo que te gusta

Origin blog.csdn.net/qq_35677589/article/details/112786004
Recomendado
Clasificación