<代码随想录> 算法训练营-2024.12.27
今日专题:动态规划、编辑距离
总结:编辑距离中,每一种编辑方式,对应一种转移方案
15. 不同的子序列
给你两个字符串 s 和 t ,统计并返回在 s 的 子序列 中 t 出现的个数,结果需要对 109 + 7 取模。
示例 1:
输入:s = "rabbbit", t = "rabbit"
输出:3
解释:
如下所示, 有 3 种可以从 s 中得到 "rabbit" 的方案。
rabbbit
rabbbit
rabbbit
class Solution:
def numDistinct(self, s: str, t: str) -> int:
#dp[i][j]-s提供到i t提供到j时,以t[j]结尾的子序列个数
size_s=len(s)
size_t=len(t)
dp=[[0]*size_t for _ in range(size_s)]
dp[0][0]=1 if s[0]==t[0] else 0
for i in range(1,size_s):
if s[i]==t[0]:
dp[i][0]=dp[i-1][0]+1
else:
dp[i][0]=dp[i-1][0]
for j in range(1,size_t):
for i in range(1,size_s):
if s[i]==t[j]:
dp[i][j]=dp[i-1][j-1]+dp[i-1][j]
else:
dp[i][j]=dp[i-1][j]
return dp[-1][-1]
583. 两个字符串的删除操作
给定两个单词 word1 和 word2 ,返回使得 word1 和 word2 相同所需的最小步数。
每步 可以删除任意一个字符串中的一个字符。
示例 1:
输入: word1 = "sea", word2 = "eat"
输出: 2
解释: 第一步将 "sea" 变为 "ea" ,第二步将 "eat "变为 "ea"
示例 2:
输入:word1 = "leetcode", word2 = "etco"
输出:4
class Solution:
def minDistance(self, word1: str, word2: str) -> int:
#dp[i][j] word1以i为结尾 word2以j为结尾完成条件所需的最小步数
size1=len(word1)+1
size2=len(word2)+1
dp=[[0]* (size2) for _ in range(size1)]
#初始化
for i in range(size1):
dp[i][0]=i
for j in range(size2):
dp[0][j]=j
for i in range(1,size1):
for j in range(1,size2):
if word1[i-1]==word2[j-1]:
dp[i][j]=dp[i-1][j-1]
else:
dp[i][j]=min(dp[i-1][j],dp[i][j-1])+1
return dp[-1][-1]
72. 编辑距离
给你两个单词 word1 和 word2, 请返回将 word1 转换成 word2 所使用的最少操作数 。
你可以对一个单词进行如下三种操作:
插入一个字符
删除一个字符
替换一个字符
示例 1:
输入:word1 = "horse", word2 = "ros"
输出:3
解释:
horse -> rorse (将 'h' 替换为 'r')
rorse -> rose (删除 'r')
rose -> ros (删除 'e')
总结:
1.相同时,dp[i][j]的值为dp[i-1][j-1]
2.不相同时
可以进行删除,取dp[i][j-1]+1
可以在dp[i-1][j]的结果上进行新增,取dp[i-1][j]+1
可以进行转换,取dp[i-1][j-1]+1
class Solution:
def minDistance(self, word1: str, word2: str) -> int:
#dp[i][j] word1以i为结尾 word2以j为结尾完成条件所需的最小步数
size1=len(word1)+1
size2=len(word2)+1
dp=[[0]* (size2) for _ in range(size1)]
#初始化
for i in range(size1):
dp[i][0]=i
for j in range(size2):
dp[0][j]=j
for i in range(1,size1):
for j in range(1,size2):
if word1[i-1]==word2[j-1]:
dp[i][j]=dp[i-1][j-1]
else:
#不相同时
#要么删除一个(dp[i][j-1])要么增加一个(dp[i-1][j])要么变换一个(dp[i-1][j-1])
dp[i][j]=min(dp[i-1][j],dp[i][j-1],dp[i-1][j-1])+1
return dp[-1][-1]