LeetCode712, la suma de eliminación ASCII más pequeña de dos cadenas

Descripción del Título

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

solución

La programación dinámica de arriba hacia abajo
lee esta pregunta, en realidad es muy similar a encontrar la subsecuencia común más larga de dos cadenas, porque aquí se busca el código ASCII más pequeño para eliminar la suma, al igual que encontrar la subsecuencia común más larga, porque hay muchos Los caracteres que salen deben borrarse, y si no son la subsecuencia común más larga, la suma de los valores del código AscII que deben borrarse debe ser mayor.

Entonces, el problema se puede resolver usando una solución similar a la subsecuencia común más larga de dos cadenas:

class Solution {
    
    
    int[][]memo;
    public int minimumDeleteSum(String s1, String s2) {
    
    
            //有想法一定要先执行,就像寻找最长公共子序一样因为多出来的字符,它们肯定要删除的
            //而不是最长公共子序,必然删除得到的AscII码值之和必然更大
        int m = s1.length(), n = s2.length();
        // 备忘录值为 -1 代表未曾计算
        memo = new int[m][n];
        for (int[] row : memo) 
            Arrays.fill(row, -1);
        return dp(s1,0,s2,0);
             
    }
    // 递归函数,自顶向下的递推,其问题的定义:计算 s1[i..] 和 s2[j..] 的最少步数
    int dp(String s1, int i, String s2, int j) {
    
    
        if (i == s1.length() ){
    
    
            int res=0;
            for(int k=j;k<s2.length();k++){
    
    
                res += s2.charAt(k);
            }
            return res;//全部删除
        }
        if(j == s2.length()) {
    
    
            int res = 0;
            for(int k=i;k<s1.length();k++){
    
    
                res += s1.charAt(k);
            }
            return res;//全部删除,此时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)+s1.charAt(i),//只需删除1个
                dp(s1, i, s2, j + 1)+s2.charAt(j)//只需删除1个
                //两个都删除的情况被包含在上面
            );
        }
        return memo[i][j];
    }
}

Inserte la descripción de la imagen aquí

Supongo que te gusta

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