712. 两个字符串的最小ASCII删除和(c++)

712. 两个字符串的最小ASCII删除和(c++)

中等

相关算法标签:LCS、动态规划

代码描述:使用迭代法(从前到后,与从后到前)、递归方法实现

/*
问题: 1.边界条件选取
       2.memo[i][j] = min(memo[i-1][j]+s1[i-1] , memo[i][j-1]+s2[j-1]);

另一种思路:
    1.使用找到最长公共子序列的最大ascii码del,用两个字符串的和减去2*del

    2.迭代法,可以从0-n,也可以从n-0

*/
class Solution {
public:
    vector<vector<int>> memo;
    int minimumDeleteSum(string s1, string s2) {
        int m = s1.size();
        int n = s2.size();
        /* 初始化memo数组,memo[i][j]表示从s1[0],s2[0]到 */
        /* s1[i],s2[j]对应的两个字符串的最小ASCII删除和*/
        memo.resize(m+1);
        for(int i=0; i<=m; i++)
        {
            memo[i].resize(n+1);
        }
        /* 边界条件 */
        /* 当j=0时,memo[i][0]的值就是s1[0-i]的ASCII和 */
        int i = m-1;
        while(i>0){
            memo[i][n] = memo[i+1][n]+s1[i];
            i--;
        }
        /* 同上,当i=0时 */
        int j=n-1;
        while(j > 0){
            memo[m][j] = memo[m][j+1]+s2[j];
            j--;
        }
        /* memo[i][j]为从0,0到i,j需要的删除的最小ASCII和*/
        i = m-1;
        while(i >= 0)
        {
            j = n-1;
            while(j >= 0)
            {
                
                /* 文本相同,一定在LCS中,不用删除 */
                if(s1[i] == s2[j])
                {
                    memo[i][j] = memo[i+1][j+1];
                }
                else
                {
                    /* 例如,要删除s1[i-1],那么memo[i-1][j]+s1[i-1] = memo[i][j]*/
                    memo[i][j] = min(memo[i+1][j]+s1[i] , memo[i][j+1]+s2[j]);
                }
                j--;
            }
            i--;
        }
        return memo[0][0];
       
    }

/* 迭代法,从前往后 */
//          int m = s1.size();
//         int n = s2.size();
//         /* 初始化memo数组,memo[i][j]表示从s1[0],s2[0]到 */
//         /* s1[i],s2[j]对应的两个字符串的最小ASCII删除和*/
//         memo.resize(m+1);
//         for(int i=0; i<=m; i++)
//         {
//             memo[i].resize(n+1);
//         }
//         /* 边界条件 */
//         /* 当j=0时,memo[i][0]的值就是s1[0-i]的ASCII和 */
//         for(int i=1; i<=m; i++){
//             memo[i][0] = memo[i-1][0]+s1[i-1];
//         }
//         /* 同上,当i=0时 */
//         for(int j=1; j<=n; j++){
//             memo[0][j] = memo[0][j-1]+s2[j-1];
//         }
//         /* memo[i][j]为从0,0到i,j需要的删除的最小ASCII和*/
//         for(int i=1; i<=m; i++)
//         {
//             for(int j=1; j<=n; j++)
//             {
//                 /* 文本相同,一定在LCS中,不用删除 */
//                 if(s1[i-1] == s2[j-1])
//                 {
//                     memo[i][j] = memo[i-1][j-1];
//                 }
//                 else
//                 {
//                     /* 例如,要删除s1[i-1],那么memo[i-1][j]+s1[i-1] = memo[i][j]*/
//                     memo[i][j] = min(memo[i-1][j]+s1[i-1] , memo[i][j-1]+s2[j-1]);
//                 }

//             }
//         }
//         return memo[m][n];

/* 递归法 */       
    /* 返回从text1[n1]、text[n2]到两个字符串末尾的删除字符的 ASCII 值的最小和 。*/
    // int LCS(string text1, int n1, string text2, int n2)
    // {
    //     int res = 0;
    //     /* base case */
    //     if(n1 == text1.size() )
    //     {
    //         while(n2 != text2.size())
    //         {
    //             res += text2[n2];
    //             n2++;
    //         }
    //         return res;
    //     }
    //     if(n2 == text2.size())
    //     {
    //         while(n1 != text1.size())
    //         {
    //             res += text1[n1];
    //             n1++;
    //         }
    //         return res;
    //     }
    //     /* 由于路径不止一条,避免重叠子问题,使用备忘录判断是否计算过 */
    //     if(memo[n1][n2] != -1)
    //     {
    //         return memo[n1][n2];
    //     }
    //     /* 文本相同,一定在LCS中 */
    //     if(text1[n1] == text2[n2])
    //     {
    //         res = LCS(text1, n1+1, text2, n2+1);
    //     }
    //     /*  文本不同,或许text1[n1]不在,或许text2[n2]不在LCS中 */
    //     else
    //     {
    //         res = min(LCS(text1, n1, text2, n2+1)+text2[n2], 
    //         LCS(text1, n1+1, text2, n2)+text1[n1]);
    //     }
    //     /* 结果输出备忘录 */
    //     memo[n1][n2] = res;
    //     return res;
    // }
};
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值