代码随想录算法训练营第四十五天 |动态规划part12
115 不同的子序列
-
确定dp数组以及下标的含义
- dp[i] [j] 以i-1为结尾的s中有以j-1为结尾的t的个数为dp[i] [j]
- 方便dp数组进行初始化操作
-
递推公式
-
if s[i-1] == t[j-1]:
遇到相同的情况,考虑使用不使用s[i-1],如果使用,那么就是dp[i-1] [j-1];如果不使用,那就是dp[i-1] [j]
dp[i] [j] = dp[i-1] [j-1] : 表示 第i个和第j个相同,所以就是前i-1,j-1个中包含t的个数
dp[i] [j] = dp[i-1] [j]:表示第i个和第j个相同,但是第不使用第i个数,bagg -> bag 不使用前者的第二个g。
dp[i] [j] = dp[i-1] [j-1] + dp[i-1] [j]
else:
就是不考虑这个元素,模拟把这个元素删除掉,不使用这个元素,只在s里面删除
dp[i] [j] = dp[i-1] [j]
-
-
dp数组如何初始化
- 初始化第一行,第一列 dp[i] [0] = 1, dp[0] [j] = 0 ,dp[0] [0] = 1
代码如下:
# s = "babgbag"
# t = "bag"
dp = [[0]*(len(t)+1) for i in range (len(s)+1)]
for i in range(len(s)):
dp[i][0] = 1
for i in range(1,len(s)+1):
for j in range(1,len(t)+1):
if s[i-1] == t[j-1]:
dp[i][j] = dp[i-1][j-1] + dp[i-1][j]
else :
dp[i][j] = dp[i-1][j]
# print(dp[-1][-1])
return dp[-1][-1]
583 两个字符串的删除操作
-
确定dp数组以及下标的含义
- dp[i] [j] 以i-1为结尾的word1 和以 j-1 为结尾的word2 为相同最少操作次数为 dp[i] [j]
-
递推公式
-
if word1[i-1] == word2[j-1]:
dp[i] [j] = dp[i-1] [j-1]
else :
dp[i] [j] = dp[i-1] [j] (不考虑word1[i-1]了) + 1 (模拟把word1[i-1]删除)
dp[i] [j] = dp[i] [j-1] + 1 (模拟把word2[j-1]删除)
dp[i] [j] = dp[i-1] [j-1] + 2 (模拟把word1[i-1],word2[j-1]都删除)
dp[i] [j] = min(dp[i-1] [j]+1,dp[i] [j-1] + 1,dp[i-1] [j-1]+2)
-
-
dp数组如何初始化
- 初始化第一行第一列,
- 第一列 dp[i] [0] = i
- 第一行 dp[0] [j] = j
代码:
dp = [[0]*(len(word2)+1) for i in range(len(word1)+1)]
for i in range(len(word1)+1):
dp[i][0] = i
for j in range(len(word2)+1):
dp[0][j] = j
for i in range(1,len(word1)+1):
for j in range(1,len(word2)+1):
if word1[i-1] == word2[j-1]:
dp[i][j] = dp[i-1][j-1]
else :
dp[i][j] = min(dp[i-1][j]+1,dp[i][j-1]+1,dp[i-1][j-1]+2)
return dp[-1][-1]
72 编辑距离
-
确定dp数组以及下标的含义
- dp[i] [j] : 以i-1 为结尾的word1 和以j-1 为结尾的word2 最少的操作次数为dp[i] [j]
-
递推公式
-
if word1[i-1] == word2[j-1]:
dp[i] [j] = dp[i-1] [j-1]
else :
增 dp[i-1] [j] + 1 dp[i] [j-1] + 1
删 dp[i-1] [j] + 1 dp[i] [j-1] + 1
替 dp[i-1] [j-1] + 1
dp[i] [j] = min(dp[i-1] [j] + 1 , dp[i] [j-1] + 1 , dp[i-1] [j-1] + 1 )
-
dp = [[0]*(len(word2)+1) for i in range(len(word1)+1)]
for i in range(len(word1)+1):
dp[i][0] = i
for j in range(len(word2)+1):
dp[0][j] = j
for i in range(1,len(word1)+1):
for j in range(1,len(word2)+1):
if word1[i-1] == word2[j-1]:
dp[i][j] = dp[i-1][j-1]
else :
dp[i][j] = min(dp[i-1][j-1]+1,dp[i][j-1]+1,dp[i-1][j]+1)
return dp[-1][-1]