LeetCode第 712 题:两个字符串的最小ASCII删除和(C++)

712. 两个字符串的最小ASCII删除和 - 力扣(LeetCode)

算是这一题LeetCode第 583 题:两个字符串的删除操作(C++)_zj-CSDN博客的进阶,这儿的目的不是使删除步数最小,而是使删除字符的ascii值最小。

动态规划

稍微修改一下状态就可以

dp[i][j]表示处理到s1中的i位字符和s2中的j位字符时,已经删除的字符的ascii码值的最小和,考虑目前正在处理第 i-1, j-1 个位置(之前的已经处理好),转移状态方程:

if(word1[i] == word2[j])	dp[i][j] = dp[i-1][j-1];//相等的时候我们什么不做
else 需要进行一次删除操作,可以删除word1的i-1字符或者word2中的j-1字符,至于删除那个好,取决于
删除哪个之后的ascii和值小,所以:
	dp[i][j] = min(dp[i-1][j] + s1[i-1], dp[i][j-1] + s2[j-1]);

反过来想,我们是如何走到(i, j)这个状态的,有三种可能:

  • (i-1, j-1)匹配,那就直接++i, ++j进入(i, j)状态
  • (i-1, j)不匹配,我们删除word1[i-1],考虑下一个状态(i, j)
  • (i, j-1)不匹配,我们删除word2[j-1],考虑下一个状态(i, j)

和583题如出一辙

class Solution {
public:
    int minimumDeleteSum(string s1, string s2) {
        int m = s1.size(), n = s2.size();
        vector<vector<int>> dp(m+1, vector<int>(n+1, 0));
        for(int i = 1; i < n+1; ++i)    dp[0][i] = dp[0][i-1] + s2[i-1];//第0行
        for(int i = 1; i < m+1; ++i)    dp[i][0] = dp[i-1][0] + s1[i-1];//第0列

        for(int i = 1; i < m+1; ++i){
            for(int j = 1; j < n + 1; ++j){
                if(s1[i-1] == s2[j-1])    dp[i][j] = dp[i-1][j-1];
                else dp[i][j] = min(dp[i-1][j] + s1[i-1], dp[i][j-1] + s2[j-1]);
            }
            //for(auto c : dp[i]) cout << c << " ";
            //cout << endl;
        }
        return dp[m][n];
    }
};

当然也类似583题,转化为最长公共子串问题(要求这些子串的ascii最大):

class Solution {
public:
    int minimumDeleteSum(string s1, string s2) {
        int m = s1.size(), n = s2.size();
        vector<vector<int>> dp(m+1, vector<int>(n+1, 0));

        for(int i = 1; i < m+1; ++i){
            for(int j = 1; j < n + 1; ++j){
                if(s1[i-1] == s2[j-1])    dp[i][j] = s1[i-1] + dp[i-1][j-1];//这儿相等的+s1[i-1]和+s2[j-1]都可以
                else dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
            }
        }
        int sum=accumulate(s1.begin(), s1.end(), 0);
        sum=accumulate(s2.begin(), s2.end(), sum);  
        return sum - 2*dp[m][n];
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值