"Editar distancia" de la serie de programación dinámica

72. Editar distancia

Dadas dos palabras word1 y word2 , calcule el número mínimo de operaciones utilizadas para convertir word1 en word2 .

Puede realizar las siguientes tres operaciones en una palabra:

  1. Insertar un personaje
  2. Eliminar un personaje
  3. Reemplazar un personaje

Ejemplo 1:

输入:word1 = "horse", word2 = "ros"
输出:3
解释:
horse -> rorse (将 'h' 替换为 'r')
rorse -> rose (删除 'r')
rose -> ros (删除 'e')

Ejemplo 2:

输入:word1 = "intention", word2 = "execution"
输出:5
解释:
intention -> inention (删除 't')
inention -> enention (将 'i' 替换为 'e')
enention -> exention (将 'n' 替换为 'x')
exention -> exection (将 'n' 替换为 'c')
exection -> execution (插入 'u')

El algoritmo de edición de distancia es ampliamente utilizado por científicos de datos, se utiliza 机器翻译y 语音识别el criterio básico de evaluación del algoritmo.

El método más intuitivo es verificar violentamente todos los métodos de edición posibles y elegir el más corto. Todos los métodos de edición posibles son exponenciales, pero no necesitamos hacer tantos cálculos porque solo necesitamos encontrar la secuencia con la distancia más corta en lugar de todas las secuencias posibles.

Podemos realizar tres operaciones sobre cualquier palabra:

Inserte un carácter;

Eliminar un personaje;

Reemplazar un carácter.

La pregunta tiene dos palabras, configuradas como A y B, de modo que podamos tener seis métodos de operación.

Pero podemos encontrar que si tenemos la palabra A y la palabra B:

  • Eliminar un carácter de la palabra A equivale a insertar un carácter de la palabra B. Por ejemplo, cuando la palabra A es dogo y la palabra B es perro, podemos eliminar el último carácter e de la palabra A para obtener el mismo perro, o agregar un carácter e al final de la palabra B para obtener el mismo dogo;

  • De la misma manera, eliminar un carácter de la palabra B equivale a insertar un carácter en la palabra A;

  • Reemplazar un carácter por la palabra A es equivalente a reemplazar un carácter por la palabra B. Por ejemplo, cuando la palabra A es murciélago y la palabra B es gato, modificamos la primera letra b -> c de la palabra A, y modificamos la primera letra c -> b de la palabra B son equivalentes.

De esta manera, podemos mantener una cadena sin cambios y simplemente manipular otra cadena. Por ejemplo, mantenga B y solo opere A:

  • 插入Un carácter en la palabra A

  • 删除 Un personaje en A

  • 修改 Un personaje en A

Como se muestra en la figura siguiente, este es uno de los métodos de edición con la distancia de edición más corta:

La distancia de edición más corta en la figura anterior es 5.

Se puede encontrar que no solo hay tres operaciones, sino que en realidad hay una cuarta operación, que es no hacer nada (omitir). Por ejemplo, cuando $ s1 [i] == s2 [j] $, ejecute i - - i--yo-- Es decir,j - - j--j--

Después de comprender el proceso anterior, lo siguiente utilizará directamente la idea de programación dinámica para resolver el problema y definir el significado de la matriz de programación dinámica:

dp[i][j]Representación s1[0...i]y s2[0...j]distancia mínima de edición.

base caseEs dp[..][0]y dp[0][..], cuando una de las cadenas representa 0, dependiendo de la distancia de edición mínima, no está seguro de que la longitud de la cadena 0, como A 0, B no sea 0, entonces la distancia de edición más corta tiene dos opciones:

  • O borre todos los caracteres de B a 0
  • O agregue caracteres a A uno por uno para que sea igual que B

Cuando $ s1 [i]! = S2 [j] $, hay tres opciones:

  • 插入Un carácter en la palabra A

  • 删除 Un personaje en A

  • 修改 Un personaje en A

Es solo que cuál de los tres elegir depende de cuál dp[i][j]se elija, así que elija el más pequeño de los tres

La implementación de Java es la siguiente :

class Solution {
    
    
    public int minDistance(String word1, String word2) {
    
    
        int m = word1.length();
        int n = word2.length();
        int[][] dp = new int[m+1][n+1];

        // base case
        for(int i = 0; i <= m; i++) dp[i][0] = i;
        for(int i = 0; i <= n; i++) dp[0][i] = i;
        
        for(int i = 1; i <= m; i++){
    
    
            for(int j = 1; j <= n; j++){
    
    
                if(word1.charAt(i-1) == word2.charAt(j-1)){
    
    
                    dp[i][j] = dp[i-1][j-1];
                }else{
    
    
                    dp[i][j] = min(
                        dp[i][j-1] + 1,
                        dp[i-1][j] + 1,
                        dp[i-1][j-1] + 1
                    );
                }
            }
        }
        return dp[m][n];
    }

    public static int min(int a, int b, int c){
    
    
        return Math.min(a, Math.min(b, c));
    }
}

Complejidad de tiempo: O (n ^ 2)

Complejidad del espacio: O (n ^ 2)

Supongo que te gusta

Origin blog.csdn.net/weixin_44471490/article/details/109267942
Recomendado
Clasificación