- 两个字符串的最小ASCII删除和
给定两个字符串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。
所有字符串中的字符ASCII值在[97, 122]之间。
思路:
从做后一个元素开始删除,两个元素相等的时候,删除代价是0。
否则选择其中一个删除,这样就形成了类似于二叉树的递归结构。递归结构可以转换成DP
# 递归的写法
class Solution:
def minimumDeleteSum(self, s1: str, s2: str) -> int:
memory = [[0]*(len(s1)+1) for _ in range(len(s2)+1)]
def dp(str_01: list, str_02: list):
len_str_01 = len(str_01)
len_str_02 = len(str_02)
if len_str_01 == 0 and len_str_02 == 0: # s1 is 空
return 0
if len_str_01 == 0:
char = str_02.pop(-1)
memory[len_str_01][len_str_02] = dp(str_01, str_02) + ord(char)
return memory[len_str_01][len_str_02]
if len_str_02 == 0:
char = str_01.pop(-1)
memory[len_str_01][len_str_02] = dp(str_01, str_02) + ord(char)
return memory[len_str_01][len_str_02]
if str_01[-1] == str_02[-1]:
memory[len_str_01][len_str_02] = dp(str_01, str_02)
return memory[len_str_01][len_str_02]
# 最后一个char不相等的情况,最终的答案一定是返回较小的一个
char01 = str_01.pop(-1)
char02 = str_02.pop(-1)
memory[len_str_01][len_str_02] = min(dp(str_01, str_02)+ord(char01),
dp(str_01, str_02)+ord(char02)
)
return memory[len_str_01-1][len_str_02-1]
return dp(list(s1), list(s2))
def func2(self, str01:str, str02:str):
# 方法二: 动态规划
len_str01 = len(str01)
len_str02 = len(str02)
str01 = list(str01)
str02 = list(str02)
# 因为有一个空字符串,所以要行列都扩加1维
dp = [[0] * (len_str01+1) for _ in range(len_str02+1)]
# 初始化数组,处理其中一个是空字符串的情况
for i in range(1, len_str01+1):
char = str01[i]
dp[0][i] = dp[0][i-1] + ord(char)
for j in range(1, len_str02+1):
char = str02[j]
dp[j][0] = dp[j-1][0] + ord(char)
for i in range(1, len_str02+1):
for j in range(1, len_str01+1):
if str01[j-1] == str02[i-1]:
dp[i][j] = dp[i-1][j-1]
else:
char01 = str01.pop(-1)
char02 = str02.pop(-1)
dp[i][j] = min(dp[i-1][j] + ord(char01),
dp[i][j-1] + ord(char02)
)
return dp[len_str02][len_str01]