一、题目描述
给定两个字符串
s1和s2,返回使两个字符串相等所需删除字符的 ASCII 值的最小和 。示例 1:
输入: s1 = "sea", s2 = "eat" 输出: 231 解释: 在 "sea" 中删除 "s" 并将 "s" 的值(115)加入总和。 在 "eat" 中删除 "t" 并将 116 加入总和。 结束时,两个字符串相等,115 + 116 = 231 就是符合条件的最小和。示例 2:
输入: s1 = "delete", s2 = "leet" 输出: 403 解释: 在 "delete" 中删除 "dee" 字符串变成 "let", 将 100[d]+101[e]+101[e] 加入总和。在 "leet" 中删除 "e" 将 101[e] 加入总和。 结束时,两个字符串都等于 "let",结果即为 100+101+101+101 = 403 。 如果改为将两个字符串转换为 "lee" 或 "eet",我们会得到 433 或 417 的结果,比答案更大。提示:
0 <= s1.length, s2.length <= 1000
s1和s2由小写英文字母组成
二、解题思路(动态规划)
 正难则反:求两个字符串的最小  ASCII  删除和, 其实就是找到两个字符串中所有的公共子序列里面, ASCII 最大和。  
 
 因此,我们的思路就是按照最长公共子序列的分析方式来分析。 
 
 
关于最长公共子序列问题,可以参考下面博客:
【力扣】最长公共子序列-CSDN博客
 1、状态表示  
 
 dp[i][j]  表示: s1  的  [0, i]  区间以及  s2  的  [0, j]  区间内的所有的子序列中,公 共子序列的  ASCII  最大和 。  
 
 
 2、状态转移方程  
  对于 dp[i][j] 根据最后一个位置的元素,结合题目要求,分情况讨论:  
  (1)当 s1[i] == s2[j] 时:应该先在 s1 的 [0, i - 1] 区间以及 s2 的 [0, j - 1] 区间内找一个公共子序列的 ASCII 最大和,然后在它们后面加上一个 s1[i] 字符即可。 
  此时 dp[i][j] = dp[i - 1][j - 1] + s1[i];  
  (2)当 s1[i] != s2[j] 时:公共子序列的ASCII最大和会有三种可能:  
 - s1 的 [0, i - 1] 区间以及 s2 的 [0, j] 区间内:此时 dp[i][j] = dp[i - 1][j] ;
- s1 的 [0, i] 区间以及 s2 的 [0, j - 1] 区间内:此时 dp[i][j] = dp[i][j - 1] ;
- s1 的 [0, i - 1] 区间以及 s2 的 [0, j - 1] 区间内:此时 dp[i][j] = dp[i - 1][j - 1] 。
 但是前两种情况里面包含了第三种情况,因此仅需考虑前两种情况下的最大值即可。  
  综上所述,状态转移方程为:  
  当 s1[i - 1] == s2[j - 1] 时, dp[i][j] = dp[i - 1][j - 1] + s1[i] ;  
  当 s1[i - 1] != s2[j - 1] 时, dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]) 
 
 3、初始化  
 
 我们将原始  dp  表的规模多加上一行和一列,表示空串。 引入空串后,大大的方便了初始化。  
 
 但要 注意下标的映射关系 ,以及里面的值要保证后续填表是正确的。  
 
 当 s1 为空时,没有长度,同理 s2 也是。因此第一行和第一列里面的值初始化为 0,即可保证  
 
 后续填表是正确的。  
 
 
 4、填表顺序  
  从上往下填每一行,每一行从左往右。  
   5、返回值 
  (1)先找到 dp[m][n] ,也是最大公共 ASCII 和;(2)统计两个字符串的 ASCII 码和 sum; (3)返回 sum - 2 * dp[m][n] 
   
三、代码
public int minimumDeleteSum(String s1, String s2) {int m = s1.length();int n = s2.length();int[][] dp = new int[m+1][n+1];for(int i = 1; i <= m; i++) {for(int j = 1; j <= n; j++) {if(s1.charAt(i-1) == s2.charAt(j-1)) {dp[i][j] = dp[i-1][j-1] + s1.charAt(i-1);}else {dp[i][j] = Math.max(dp[i][j-1], dp[i-1][j]);}}}int sum = 0;for(char ch : s1.toCharArray()) {sum += ch;}for(char ch : s2.toCharArray()) {sum += ch;}return sum - dp[m][n] - dp[m][n];}