Cómo encontrar los cambios mínimos necesarios para convertir una cuerda en un palíndromo

Su solución asume fatalmente que alguna vez necesitará agregar solo 1 carácter al final.

si (s [i] == s [j])
retorno ret = rec (i + 1, j-1);
más {
if (j == s.length () – 1)
ret = min (rec (i + 1, j-1), rec (i + 1, j)) + 1;
más
ret = rec (i + 1, j-1) + 1;
volver ret;
}

La línea 1,2 de su código básicamente dice que si la primera y la última letra son iguales, podemos pasar al subproblema sin estos dos caracteres. Sin embargo, esto no es correcto. Por ejemplo, tome la cadena “aabcba”, su solución intentará resolver “abcb” y nunca alcanzará la solución correcta, es decir, “aabcbaa”

La línea 4 trata la situación, si el primer y el último carácter no son iguales, entonces tenemos que agregar una copia del primer carácter al final de la cadena, o cambiamos el último carácter al primer carácter. Y ahora es lo mismo que la línea 1,2, es decir, recorta los dos caracteres en los puntos finales y resuelve el problema secundario.

La línea 6,7 ​​trata la misma situación para las subcadenas de la cadena original.

Tome el ejemplo de “abcdedc”, su solución cambiará la última ‘c’ a ‘a’ y resolverá el subproblema “bcded” o agregará una ‘a’ al final y resolverá “bcdedc”.

Y probablemente termine con la solución “abcdcba” con número de ediciones = 3.

Ninguno de estos conducirá a la verdadera solución que es “abcdedcba” (agregue dos caracteres “ba” al final), que necesita explorar el subproblema “abcdedcb” (o una variante del mismo).

Yo diría que la línea 4 es el problema en su código.

Si tuviera que resolver este problema, lo resolvería un poco diferente.

Usaría una matriz 3D para realizar un seguimiento de todos los cambios, y al mismo tiempo realizar un seguimiento de las cadenas intermedias que se generan como resultado de las ediciones. Dado que la comprobación de palíndromo debe ocurrir en la cadena intermedia y no en la cadena original.

Las tablas de memorización se verán de la siguiente manera

Nombres de cadena [100] [100] [26];
int pathLength [100] [100] [26];

Inicialice los nombres de las tablas con todas las entradas nulas. Una entrada particular de esta tabla, digamos nombres [i] [j] [k] , se refiere a la cadena que tiene ‘i + 1’ caracteres de largo, con el carácter j-th reemplazado por el carácter ‘k’ (k = 0 -> a, k = 25 -> z).

La tabla pathLength realiza un seguimiento del número de cambios que realizamos para llegar a una variante particular del nombre. Inicialice esta tabla con todos los valores iguales a Infinito Positivo.

Comenzaremos ingresando la primera entrada que será,

nombres [len (nombre) – 1] [0] [nombre [0]] = nombre;
nombres [len (nombre) – 1] [1] [nombre [1]] = nombre;
.
.
nombres [len (nombre) – 1] [len (nombre) – 1] [nombre [len (nombre) – 1]] = nombre;

pathLength [len (nombre) – 1] [0] [nombre [0]] = 0;
pathLength [len (nombre) – 1] [1] [nombre [1]] = 0;
.
.
pathLength [len (nombre) – 1] [len (nombre) – 1] [nombre [len (nombre) – 1]] = 0;

desde aquí tendremos que explorar los otros estados a los que se puede llegar desde este punto, que básicamente es que cada letra se puede reemplazar con una nueva letra o podemos agregar una nueva letra al final. Mantenga una cola para realizar un seguimiento de todos los estados que necesita procesar. Y cada vez que visita una posición no nula en la matriz, sabe que ese estado se ha alcanzado previamente y no necesita explorarlo más. Dado que la exploración del estado está ocurriendo de una manera amplia primero. El primer palíndromo que encuentres de esta manera será tu respuesta.

Podemos trabajar con el ejemplo 1 proporcionado en la pregunta, a saber.

input = kaia.

comenzamos con poblar

nombres [3] [0] [10] = “kaia”, pathLength [3] [0] [10] = 0;
nombres [3] [1] [0] = “kaia”, pathLength [3] [1] [0] = 0;
nombres [3] [2] [8] = “kaia”, pathLength [3] [2] [8] = 0;
nombres [3] [3] [0] = “kaia”, pathLength [3] [3] [0] = 0;

podemos cambiar cualquiera de estas letras a otra o agregar una letra al final.

Entonces actualizamos

nombres [3] [0] [0 … 25 excepto 10] = carácter + “aia”, longitud de ruta [3] [0] [0 … 25 excepto 10] = 1
nombres [3] [1] [1… 25] = “k” + carácter + “ia”, longitud de ruta [3] [1] [1… 25] = 1
nombres [3] [2] [0… 26 excepto 8] = “ka” + carácter + “a”, pathLength [3] [2] [0… 26 excepto 8] = 1
nombres [3] [3] [1..25] = “kai” + carácter, longitud de ruta [3] [3] [1..25] = 1
nombres [4] [4] [0..26] = “kaia” + carácter, pathLength [4] [4] [0..26] = 1

y agregarlos a la cola. A medida que procesemos estos y agreguemos los estados accesibles desde ellos, notaremos que el nombre [4] [4] [10] = “kaiak” es un palíndromo y el pathLength correspondiente es 1. es decir, solo tuvimos que hacer 1 modificación al nombre original para llegar a este palíndromo.

Propongo aquí una solución simple:

Pruebe todas las longitudes de la salida en el rango de n a 2n (donde n es la longitud de la entrada).

Para cada longitud de salida, es muy fácil calcular la cantidad de cambios necesarios y luego debe elegir la mejor opción.

More Interesting

¿Qué tipo de algoritmo de programación de CPU se utiliza actualmente en los sistemas operativos?

¿Qué es un algoritmo eficiente para encontrar una isla de 1s conectados en una matriz de 0s y 1s?

Cómo implementar un código C para la eliminación de un nodo de una lista vinculada considerando todos los casos de prueba

¿Puede mostrar que la ordenación por fusión tiene complejidad de tiempo [matemática] O (n \ log n) [/ matemática]?

No puedo entender algoritmos y estructuras de datos. ¿Cómo puedo aprender algoritmos y estructuras de datos de una manera simple?

¿Es posible aprender automáticamente los diferentes métodos y algoritmos de aprendizaje automático?

Cómo aprender algoritmos anticolisión RFID

¿Cuáles son algunos buenos tutoriales que dividen, conquistan y analizan los algoritmos más complejos jamás diseñados?

Estoy obteniendo una precisión del 52% en los datos de mi celda, como el volumen, etc., que son valores extremadamente pequeños. He usado el árbol de decisión. ¿Cómo puedo mejorar?

¿Qué viene después de aprender la biblioteca de plantillas estándar, las estructuras de datos y los algoritmos en C ++?

¿Es posible construir un algoritmo (para ejecutar en una computadora con recursos de espacio finito) que tomará como entrada un flujo de lanzamientos de monedas al azar imparciales (probabilidad independiente de caras 1/2) y emitirá caras con probabilidad irracional esperada?

Cómo comprender la recursividad en backtracking de campo profundo y todo relacionado, programación dinámica, etc.

¿Se puede usar el algoritmo DBSCAN para determinar los límites del área geográfica?

Cómo escribir un programa para ingresar una cadena e imprimir el número de caracteres en minúscula y mayúscula en la cadena

¿Cuál es el error lógico en mi siguiente código para la multiplicación de karatsuba?