712. 两个字符串的最小ASCII删除和(c++)
中等
相关算法标签:LCS、动态规划
代码描述:使用迭代法(从前到后,与从后到前)、递归方法实现
/*
问题: 1.边界条件选取
2.memo[i][j] = min(memo[i-1][j]+s1[i-1] , memo[i][j-1]+s2[j-1]);
另一种思路:
1.使用找到最长公共子序列的最大ascii码del,用两个字符串的和减去2*del
2.迭代法,可以从0-n,也可以从n-0
*/
class Solution {
public:
vector<vector<int>> memo;
int minimumDeleteSum(string s1, string s2) {
int m = s1.size();
int n = s2.size();
/* 初始化memo数组,memo[i][j]表示从s1[0],s2[0]到 */
/* s1[i],s2[j]对应的两个字符串的最小ASCII删除和*/
memo.resize(m+1);
for(int i=0; i<=m; i++)
{
memo[i].resize(n+1);
}
/* 边界条件 */
/* 当j=0时,memo[i][0]的值就是s1[0-i]的ASCII和 */
int i = m-1;
while(i>0){
memo[i][n] = memo[i+1][n]+s1[i];
i--;
}
/* 同上,当i=0时 */
int j=n-1;
while(j > 0){
memo[m][j] = memo[m][j+1]+s2[j];
j--;
}
/* memo[i][j]为从0,0到i,j需要的删除的最小ASCII和*/
i = m-1;
while(i >= 0)
{
j = n-1;
while(j >= 0)
{
/* 文本相同,一定在LCS中,不用删除 */
if(s1[i] == s2[j])
{
memo[i][j] = memo[i+1][j+1];
}
else
{
/* 例如,要删除s1[i-1],那么memo[i-1][j]+s1[i-1] = memo[i][j]*/
memo[i][j] = min(memo[i+1][j]+s1[i] , memo[i][j+1]+s2[j]);
}
j--;
}
i--;
}
return memo[0][0];
}
/* 迭代法,从前往后 */
// int m = s1.size();
// int n = s2.size();
// /* 初始化memo数组,memo[i][j]表示从s1[0],s2[0]到 */
// /* s1[i],s2[j]对应的两个字符串的最小ASCII删除和*/
// memo.resize(m+1);
// for(int i=0; i<=m; i++)
// {
// memo[i].resize(n+1);
// }
// /* 边界条件 */
// /* 当j=0时,memo[i][0]的值就是s1[0-i]的ASCII和 */
// for(int i=1; i<=m; i++){
// memo[i][0] = memo[i-1][0]+s1[i-1];
// }
// /* 同上,当i=0时 */
// for(int j=1; j<=n; j++){
// memo[0][j] = memo[0][j-1]+s2[j-1];
// }
// /* memo[i][j]为从0,0到i,j需要的删除的最小ASCII和*/
// for(int i=1; i<=m; i++)
// {
// for(int j=1; j<=n; j++)
// {
// /* 文本相同,一定在LCS中,不用删除 */
// if(s1[i-1] == s2[j-1])
// {
// memo[i][j] = memo[i-1][j-1];
// }
// else
// {
// /* 例如,要删除s1[i-1],那么memo[i-1][j]+s1[i-1] = memo[i][j]*/
// memo[i][j] = min(memo[i-1][j]+s1[i-1] , memo[i][j-1]+s2[j-1]);
// }
// }
// }
// return memo[m][n];
/* 递归法 */
/* 返回从text1[n1]、text[n2]到两个字符串末尾的删除字符的 ASCII 值的最小和 。*/
// int LCS(string text1, int n1, string text2, int n2)
// {
// int res = 0;
// /* base case */
// if(n1 == text1.size() )
// {
// while(n2 != text2.size())
// {
// res += text2[n2];
// n2++;
// }
// return res;
// }
// if(n2 == text2.size())
// {
// while(n1 != text1.size())
// {
// res += text1[n1];
// n1++;
// }
// return res;
// }
// /* 由于路径不止一条,避免重叠子问题,使用备忘录判断是否计算过 */
// if(memo[n1][n2] != -1)
// {
// return memo[n1][n2];
// }
// /* 文本相同,一定在LCS中 */
// if(text1[n1] == text2[n2])
// {
// res = LCS(text1, n1+1, text2, n2+1);
// }
// /* 文本不同,或许text1[n1]不在,或许text2[n2]不在LCS中 */
// else
// {
// res = min(LCS(text1, n1, text2, n2+1)+text2[n2],
// LCS(text1, n1+1, text2, n2)+text1[n1]);
// }
// /* 结果输出备忘录 */
// memo[n1][n2] = res;
// return res;
// }
};