LeetCode583, operación de eliminación de dos cadenas

Descripción del Título

https://leetcode-cn.com/problems/delete-operation-for-two-strings/
Inserte la descripción de la imagen aquí

solución

Recursión (programación dinámica de arriba hacia abajo)

class Solution {
    
    
// 备忘录,消除重叠子问题
int[][] memo;
    public int minDistance(String word1, String word2) {
    
    
        int m = word1.length(), n = word2.length();
        // 备忘录值为 -1 代表未曾计算
        memo = new int[m][n];
        for (int[] row : memo) 
            Arrays.fill(row, -1);
        // 计算 s1[0..] 和 s2[0..] 的 lcs 长度
        return dp(word1, 0, word2, 0);
    }

// 递归函数,自顶向下的递推,其问题的定义:计算 s1[i..] 和 s2[j..] 的最少步数
int dp(String s1, int i, String s2, int j) {
    
    
    if (i == s1.length() ){
    
    
        return s2.length()-j;
    }
    if(j == s2.length()) {
    
    
        return s1.length()-i;//全部删除,此时s2为“”,则需要把s1全删除
    }
    // 如果之前计算过,则直接返回备忘录中的答案
    if (memo[i][j] != -1) {
    
    
        return memo[i][j];
    }
    // 根据 s1[i] 和 s2[j] 的情况做选择
    if (s1.charAt(i) == s2.charAt(j)) {
    
    
        memo[i][j] = dp(s1, i + 1, s2, j + 1);
    } else {
    
    
        memo[i][j] = Math.min(
            dp(s1, i + 1, s2, j)+1,//只需删除1个
            dp(s1, i, s2, j + 1)+1//只需删除1个
            //两个都删除的情况被包含在上面
        );
    }
    return memo[i][j];
}

}

Inserte la descripción de la imagen aquí

Programación dinámica (de abajo hacia arriba)

class Solution {
    
    
    public int minDistance(String word1, String word2) {
    
    
        int m = word1.length(), n = word2.length();
        //使用自顶向下和自底向上的dp数组定义方向相反
        int[][]dp = new int[m+1][n+1];//表示使得s[0,m-1]和s[0,n-1]相同的最少步数

        //边界条件:dp[0][n+1]和dp[m+1][0]表示有一个字符串是空串,则直接将另外一个全删除
        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] = Math.min(
                    dp[i-1][j]+1,
                    dp[i][j-1]+1
                );
            }
        }
        return dp[m][n];
      
    }

}

Inserte la descripción de la imagen aquí

En la programación dinámica anterior, la recursividad solo está relacionada con unas pocas variables adyacentes, y podemos usar la compresión de estado para optimizar la complejidad del espacio.

Puede consultar la solución oficial:
https://leetcode-cn.com/problems/delete-operation-for-two-strings/solution/liang-ge-zi-fu-chuan-de-shan-chu-cao- zuo-by -leetco /

Piénsalo desde otro ángulo: el
título nos permite calcular el número mínimo de eliminaciones para que dos cadenas sean iguales. Al final, ¿qué se eliminarán las dos cadenas? ¡El resultado de la eliminación no es la subsecuencia común más larga de las dos!

Luego, para calcular el número de eliminaciones, se puede derivar de la longitud de la subsecuencia común más larga:

int minDistance(String s1, String s2) {
    
    
    int m = s1.length(), n = s2.length();
    // 复用前文计算 最长公共子序长度的函数
    int lcs = longestCommonSubsequence(s1, s2);
    return m - lcs + n - lcs;
}

Supongo que te gusta

Origin blog.csdn.net/qq_44861675/article/details/114480892
Recomendado
Clasificación