【算法分析与设计】【第八周】712. Minimum ASCII Delete Sum for Two Strings

来源:互联网 发布:华为网络管理系统 编辑:程序博客网 时间:2024/06/16 10:46

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

复习动态规划,最小编辑距离问题。

  • 题目大意
  • 思路
    • 最小编辑距离问题回顾
      • 例子
      • 算法简析
      • 复杂度
      • 伪代码
      • 代码
        • 动态规划版本
        • 递归版本
    • 本题思路
      • 解题代码
      • discuss里的优化

题目大意

给定字符串s1, s2。删除其中的一些字符使得两字符串相等
删除字符的代价是被删字符ASCII之和,求最小代价。


思路

建立在对“最小编辑距离”问题的理解上。

“最小编辑距离”问题回顾

编辑距离(Edit Distance),又称Levenshtein距离,是指两个字串之间,由一个转成另一个所需的最少编辑操作次数。
可以编辑的操作有:

  • 增补
  • 删除
  • 替换

例子

例:S N O W Y -> S U N N Y
[转换方式一]
S _ N O W Y
S U N N _ Y
操作:增1,删1,替1
cost:3

[转换方式二]
_ S N O W _ Y
S U N _ _ N Y
操作:增2,删2,替1
cost:5

[转换方式…]
……

编辑距离:min{cost1,cost2,…} = 3

算法简析

动态规划,把问题缩小为子问题。
还是以上述例子为例,假设转变为SUNNY的最后一步为X串->SUNNY。
那么无非分为三种情况:
(1)X串的长度为6,且SUNNY是X串的子序列。这样,只需要在X串上执行一步“删除”操作,删除相应的字母即可得到SUNNY;
(2)X串的长度为4,且X串是SUNNY的子序列。这样,只需要在X串上执行一步“增补”操作,增补相应的字母即可得到SUNNY;
(3)X串的长度为5,此时分两种情况讨论:一是X串的最后一个字母不是Y,那么需要在X串上执行一步“替换”操作;二是X串的最后一个字母是Y,那么X串即SUNNY。
其余情况均无法一步变为SUNNY,也就无法算作是最后一步了。
将以上三种情况的操作步数表示成数对的形式(i表示X串的长度,j表示SUNNY的长度):
(1)E(5, 5) = E(4, 5)+1
(2)E(5, 5) = E(5, 4)+1
(3)E(5, 5) = E(4, 4)+diff(5, 5) diff(5, 5) = 0 or 1

所以我们很容易得出核心状态转移式:
E(i, j) = min{E(i-1, j)+1, E(i, j-1)+1, E(i-1, j-1)+diff(i, j)}

画出完整的E矩阵

S U N N Y 0 1 2 3 4 5 0 0 1 2 3 4 5 S 1 1 0 1 2 3 4 N 2 2 1 1 1 2 3 O 3 3 2 2 2 2 3 W 4 4 3 3 3 3 3 Y 5 5 4 4 4 4 3

min cost = E(5, 5) = 3

复杂度

状态数:O(mn)
状态转移复杂度:O(1)

伪代码

for i = 0 : m:  E(i, 0) = ifor j = 1 : n:  E(0, j) = jfor i = 1 : m:  for j = 1 : n:    E(i. j) = min{E(i-1, j)+1, E(i, j-1)+1, E(i-1, j-1)+diff(i, j)}return E(m, n)

代码

参考youngwind的代码。

动态规划版本

int dynamicPlanning(string a, string b) {    int lenA = a.length();    int lenB = b.length();    int E[lenA+1][lenB+1];    for (int i = 0; i <= lenA; i++) {        E[i][0] = i;    }    for (int j = 1; j <= lenB; j++) {        E[0][j] = j;    }    for (int i = 1; i <= lenA; i++) {        for (int j = 1; j <= lenB; j++) {            if (a[i - 1] == b[j - 1]) {                E[i][j] = E[i - 1][j - 1];            } else {                int m1 = E[i - 1][j] + 1;                int m2 = E[i][j - 1] + 1;                int m3 = E[i - 1][j - 1] + 1;                E[i][j] = min(m1, m2, m3);            }        }    }    return E[lenA][lenB];}

递归版本

int recursion(string a, string b, int i, int j) {    if (j == 0) {        return i;    } else if (i == 0) {        return j;    } else if (a[i - 1] == b [j - 1]) {        return recursion(a, b, i - 1, j - 1);    } else {        int m1 = recursion(a, b, i - 1, j) + 1;        int m2 = recursion(a, b, i, j - 1) + 1;        int m3 = recursion(a, b, i - 1, j - 1) + 1;        return min(m1, m2, m3);    }}

《算法概论》P159

本题思路

和最小编辑距离相似。

解题代码

已通过leetcode

int minimumDeleteSum(string s1, string s2) {      int lenA = s1.length();      int lenB = s2.length();      int E[lenA+1][lenB+1] = {0};      for (int i = 1; i <= lenA; i++) {          E[i][0] = E[i-1][0] + s1[i-1];      }      for (int j = 1; j <= lenB; j++) {          E[0][j] = E[0][j-1] + s2[j-1];      }      for (int i = 1; i <= lenA; i++) {          for (int j = 1; j <= lenB; j++) {              if (s1[i - 1] == s2[j - 1]) {                  E[i][j] = E[i - 1][j - 1];              } else {                  int m1 = E[i - 1][j] + s1[i-1];                  int m2 = E[i][j - 1] + s2[j - 1];                  //int m3 = E[i - 1][j - 1] + 1;                  //E[i][j] = min(m1, m2, m3);                  E[i][j] = min(m1, m2);              }          }      }      return E[lenA][lenB];        }

discuss里的优化

Optimized O(n) extra space

class Solution {public:    int minimumDeleteSum(string s1, string s2) {        int m = s1.size(), n = s2.size();        vector<int> dp(n+1, 0);        for (int j = 1; j <= n; j++)            dp[j] = dp[j-1]+s2[j-1];        for (int i = 1; i <= m; i++) {            int t1 = dp[0];            dp[0] += s1[i-1];            for (int j = 1; j <= n; j++) {                int t2 = dp[j];                dp[j] = s1[i-1] == s2[j-1]? t1:min(dp[j]+s1[i-1], dp[j-1]+s2[j-1]);                t1 = t2;            }        }        return dp[n];    }};
阅读全文
0 0