博主有个小小的强迫症,那就是——喜欢总结东西!
所以最近在总结Leetcode套路(动态规划、回溯)的时候,我debug了3个小时!
现在让我们看看这道题(我细节没想清楚,所以错了)
有兴趣的同学可以自己去尝试下:
这里我写下我的3种解决方案(表示记忆深刻!!!)
对于常见的算法而言,本质上都是穷举(或者通过剪枝/状态转移方程进行优化)
以下写下递归解法、加了备忘录的递归解法、以及dp。
前两种是自上而下的,最后一种是自下而上的。
通过3种解法基本上可以构建一个这类题的一个思路体系!
递归解法:
## 直接递归
def minDistance1(s1,s2):
def dp(i,j):
# base case
if i == -1: return j + 1
if j == -1: return i + 1
if s1[i] == s2[j]:
return dp(i - 1, j - 1)
else:
return min(
dp(i, j - 1) + 1,
dp(i - 1, j) + 1,
dp(i - 1, j-1) + 1
)
# i,j 初始化指向最后一个索引
return dp(len(s1) - 1,len(s2) - 1)
加了备忘录的递归解法:
def minDistance2(s1,s2):
memo = dict() # 备忘录(以元组形成字典)
def dp(i,j):
if (i, j) in memo:
return memo[(i, j)]
# base case
if i == -1: return j + 1
if j == -1: return i + 1
if s1[i] == s2[j]:
memo[(i,j)] = dp(i - 1, j - 1)
else:
memo[(i,j)] = min(
dp(i, j - 1) + 1,
dp(i - 1, j) + 1,
dp(i - 1, j-1) + 1
)
return memo[(i,j)]
# i,j 初始化指向最后一个索引
return dp(len(s1) - 1,len(s2) - 1)
def minDistance3(s1,s2):
# 二维数组的创建(行为s1、列为s2)
dp =[ [0] * (len(s2)+1) for _ in range(len(s1)+1)]
#base case(表示全进行删除eg:"" 和"avc"等)
for i in range(len(s1)+1): #行
dp[i][0] = i
for j in range(len(s2)+1): #列
dp[0][j] = j
for i in range(1,len(dp)):
for j in range(1,len(dp[0])):
if s1[i-1] == s2[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] +1
)
return dp[-1][-1]
总结:花费了3小时,发现只是一个小错误,不仅枯了,思路还更清晰了