题目内容
题目要求:给定两个字符串s1, s2,找到使两个字符串相等所需删除字符的ASCII值的最小和。
解题思路
解题思路:此题为为最长公共子序列的变形
- 定义:
s1[0..i-1]
和s2[0..j-1]
的最小ascii码删除和dp[i][j]
- 目标:
s1[0..m-1]
和s2[0..n-1]
的最小ascii码删除和,即dp[m][n]
- base case:
dp[0][..]
对应的(有长度的)字符串ascii码的和,因为如果一个字符串为空,另一个字符串必然要被全部删除,所以需要计算另一个字符串所有字符的 ASCII 码之和。
代码实现
class Solution {
public int minimumDeleteSum(String s1, String s2) {
int m=s1.length(),n=s2.length();
int [][]dp=new int[m+1][n+1];
//定义时dp的0为basecase状态,意味着这个字符串是空串没有长度,所以另一个字符串必然要被全部删除,需要计算另一个字符串所有字符的 ASCII 码之和。
//dp这个二维数组的1才是对应着实际字符串的第零位,注意区分相当于逻辑位置和实际位置
for(int i=1;i<=m;i++)
{
//0意味着字符串是空的
dp[i][0]=dp[i-1][0]+s1.charAt(i-1);
}
for(int i=1;i<=n;i++)
{
dp[0][i]=dp[0][i-1]+s2.charAt(i-1);
}
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
// s1[i] 和 s2[j] 都是在 lcs 中的,不用删除
if(s1.charAt(i-1)==s2.charAt(j-1)) dp[i][j]=dp[i-1][j-1];
else{
// s1[i] 和 s2[j] 至少有一个不在 lcs 中,删一个,加上他的ascii,码的和, 选择最小的作为我们的dp[i][j];
//dp中的i对应着实际字符串的i-1
//dp[i][j - 1]+s2.charAt(j-1) 即因为 s1[i-1] 和 s2[j-1]不相等,所以我们去考虑dp[i][j - 1]加上s2中第j个字符ascii码的情况
dp[i][j]=Math.min(dp[i][j - 1]+s2.charAt(j-1), dp[i - 1][j]+s1.charAt(i-1));
}
}
}
return dp[m][n];
}
}