【Leetcode】712. Minimum ASCII Delete Sum for Two Strings

题目地址:

https://leetcode.com/problems/minimum-ascii-delete-sum-for-two-strings/description/

给定两个字符串 s 1 , s 2 s_1,s_2 s1,s2,可以删除任一字符串的任意多个字符,总代价为删除的字符的ASCII码总和。求让它们变得相等的最小总代价。

f [ i ] [ j ] f[i][j] f[i][j] s 1 s_1 s1 i i i个字符的前缀和 s 2 s_2 s2 j j j个字符的前缀要变得相等,操作的最小总代价。那么 f [ 0 ] [ 0 ] = 0 f[0][0]=0 f[0][0]=0。接下来下标从 1 1 1开始,可以按照 s 1 [ i ] s_1[i] s1[i] s 2 [ j ] s_2[j] s2[j]是否做删除来分类,如果删 s 1 [ i ] s_1[i] s1[i],则最小总代价为 f [ i − 1 ] [ j ] + s 1 [ i ] f[i-1][j]+s_1[i] f[i1][j]+s1[i];如果删 s 2 [ j ] s_2[j] s2[j],结论类似;如果都删,则最小总代价为 f [ i − 1 ] [ j − 1 ] + s 1 [ i ] + s 2 [ j ] f[i-1][j-1]+s_1[i]+s_2[j] f[i1][j1]+s1[i]+s2[j];如果 s 1 [ i ] = s 2 [ j ] s_1[i]=s_2[j] s1[i]=s2[j],那么不删也是一种选择,最小总代价为 f [ i − 1 ] [ j − 1 ] f[i-1][j-1] f[i1][j1]。四个情况取最小即可。代码如下:

class Solution {
 public:
  int minimumDeleteSum(string s1, string s2) {
    int m = s1.size(), n = s2.size();
    s1 = " " + s1, s2 = " " + s2;
    int f[m + 1][n + 1];
    memset(f, 0x3f, sizeof f);
    f[0][0] = 0;
    for (int i = 0; i <= m; i++)
      for (int j = 0; j <= n; j++) {
        if (!i && !j) continue;
        if (!i) f[i][j] = f[i][j - 1] + s2[j];
        else if (!j) f[i][j] = f[i - 1][j] + s1[i];
        else {
          f[i][j] = min(f[i - 1][j] + s1[i], f[i][j - 1] + s2[j]);
          if (s1[i] == s2[j]) f[i][j] = min(f[i][j], f[i - 1][j - 1]);
          else f[i][j] = min(f[i][j], f[i - 1][j - 1] + s1[i] + s2[j]);
        }
      }
    return f[m][n];
  }
};

时空复杂度 O ( l s 1 l s 2 ) O(l_{s_1}l_{s_2}) O(ls1ls2)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值