LEETCODE专题
712. Minimum ASCII Delete Sum for Two Strings
题目要求:
这里题目要求我们求出输入的两个字符串的“最小删除距离”。所谓“删除距离”,也就是将两个字符串中除最长匹配序列以外的其它字符删除的“距离”,也就是ascii码值。而“最小删除距离”是指在删除的过程中,有可能存在不同的最长匹配序列,譬如题目所给的第2个例子中:
Input: s1 = "delete", s2 = "leet"
对于这两个字符串,可以找到3个最长匹配序列:”let”、”lee”和”eet”。每一个保留的最长匹配序列及其对应的删除距离如下表所示:
保留序列 | 最长距离 |
---|---|
let | 403 |
lee | 433 |
eet | 417 |
所以,可以得到的”最小删除距离“是403。
问题:
- 这个问题的子问题是什么?得到了子问题后如何复用子问题的结果?
思路:
- 我们可以得到这是一个前缀问题:匹配的序列位于2个字符串的前面。若结果存储的刚好是最小删除距离,那么计算当前下标的匹配序列就可以判断当前下标的两个字符串的字符是否匹配,若匹配,我们可以不删除这2个字符,复用之前的结果就可以了,当然也可以同时删除掉这2个字符再加上之前的结果;若不匹配,我们可以选择删除第一个字符串中的当前字符,也可以选择删除第二个字符串中的当前字符所得到的结果分别加上对应的之前的结果。这几种情况计算得出的最小值就是我们要求的结果。
- 此外,关于上述的如何判断的问题,代码中有比较详细的注释,就不在此一一赘述了。
下面直接上代码:
class Solution {
public:
int minimumDeleteSum(string s1, string s2) {
/*
* Initialize a 2-D array to store the minimumDeleteSum
* of the substrings of these 2 strings with the first
* index the length of the substring of the s1 and the
* second one the length of the substring of the s2.
*
* There is 3 ways we can use to get the current
* minimumDeleteSum, named minDeleteLength[i][j]
* 1. minDeleteLength[i][j] = minDeleteLength[i - 1][j] + s1[i - 1]
* that means the first i - 1 chars of s1 and the first
* j chars of s2 are matched better, and s1[i - 1]
* should be deleted.
*
* 2. minDeleteLength[i][j] = minDeleteLength[i][j - 1] + s2[j - 1]
* that means the first i chars of s1 and the first
* j - 1 chars of s2 are matched better, and s1[i - 1]
* should be deleted.
*
* 3. minDeleteLength[i][j] = minDeleteLength[i - 1][j - 1]( + s1[i - 1] + s2[j - 1])
* that means now s1[i - 1] and s2[j - 1] should both
* be deleted, if s1[i -1] and s2[j - 1] are matched,
* then we can omit the deleteLength of s1[i - 1] and
* s2[j - 1], else we must add them.
*/
int ** minDeleteLength = new int*[s1.length() + 1];
int i, j, min;
for (i = 0; i < s1.length() + 1; i++) {
minDeleteLength[i] = new int[s2.length() + 1];
}
minDeleteLength[0][0] = 0;
for (i = 0; i < s1.length() + 1; i++) {
for (j = 0; j < s2.length() + 1; j++) {
if (i == 0 && j == 0) {
continue;
} else if (i == 0 && j != 0) {
minDeleteLength[0][j] = minDeleteLength[0][j - 1] + s2[j - 1];
} else if (i != 0 && j == 0) {
minDeleteLength[i][0] = minDeleteLength[i - 1][0] + s1[i - 1];
} else {
int t1, t2, t3;
t1 = minDeleteLength[i - 1][j] + s1[i - 1];
t2 = minDeleteLength[i][j - 1] + s2[j - 1];
min = t1 < t2 ? t1 : t2;
if (s1[i - 1] == s2[j - 1]) {
t3 = minDeleteLength[i - 1][j - 1];
} else {
t3 = minDeleteLength[i - 1][j - 1] + s1[i - 1] + s2[j - 1];
}
minDeleteLength[i][j] = min < t3 ? min : t3;
}
}
}
min = minDeleteLength[s1.length()][s2.length()];
for (i = 0; i < s1.length() + 1; i++) {
delete []minDeleteLength[i];
}
delete []minDeleteLength;
return min;
}
};
时间复杂度:O(n^2)