【算法分析与设计】【第八周】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矩阵
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]; }};
- 【算法分析与设计】【第八周】712. Minimum ASCII Delete Sum for Two Strings
- Minimum ASCII Delete Sum for Two Strings
- Minimum ASCII Delete Sum for Two Strings
- Leetcode 712 Minimum ASCII Delete Sum for Two Strings (算法分析week13)
- Leetcode 712. Minimum ASCII Delete Sum for Two Strings
- 712. Minimum ASCII Delete Sum for Two Strings
- LWC 55:712. Minimum ASCII Delete Sum for Two Strings
- [leetcode] 712. Minimum ASCII Delete Sum for Two Strings
- 712. Minimum ASCII Delete Sum for Two Strings
- 712. Minimum ASCII Delete Sum for Two Strings
- 712. Minimum ASCII Delete Sum for Two Strings
- 712. Minimum ASCII Delete Sum for Two Strings
- Leetcode: 712. Minimum ASCII Delete Sum for Two Strings
- 712. Minimum ASCII Delete Sum for Two Strings
- 712. Minimum ASCII Delete Sum for Two Strings
- 712. Minimum ASCII Delete Sum for Two Strings
- 712. Minimum ASCII Delete Sum for Two Strings
- 712. Minimum ASCII Delete Sum for Two Strings
- 访问者模式学习和思考
- 动态规划--机器分配
- 红黑瓷砖
- 输入N阶方阵求其各行各列的和
- 76. Minimum Window Substring
- 【算法分析与设计】【第八周】712. Minimum ASCII Delete Sum for Two Strings
- Lintcode-动态规划-不同路径二
- 设置单文档CListView视图中列表的行高
- 57. Insert Interval
- 《深入理解Java虚拟机》——字节码指令简介
- 深度学习目标检测最全最新的方法paper和代码
- Java过滤器和SpringMVC拦截器之间的关系与区别
- 在CentOS 7上安装RabbitMQ服务器
- Node* create()的含义