Leetcode之编辑距离
题目:
递归
定义dp函数:dp(i,j)表示word1[0…i]转成word2[0…j]的最少操作数
def minDistance(word1,word2):
def dp(i,j):
#递归的终点
#word1走到头,要将word2剩余的字符插入
if i == -1:
return j + 1
#word2走到头,要将word1剩余的字符删除
if j == -1:
return i + 1
#相同则不动,指针向前移动
if word1[i] == word2[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#替换
)
return dp(len(word1)-1,len(word2)-1)
但该方法超出时间限制,需要用动态规划优化一下
数组备忘录优化
class Solution:
def minDistance(self, word1: str, word2: str) -> int:
def dp(i,j):
if i < 0:
return j + 1
if j < 0:
return i + 1
if memo[i][j] != m + n + 1:
return memo[i][j]
if word1[i] == word2[j]:
memo[i][j] = dp(i-1,j-1)
else:
memo[i][j] = min(
dp(i-1,j) + 1,
dp(i,j-1) + 1,
dp(i-1,j-1) + 1
)
return memo[i][j]
m = len(word1)
n = len(word2)
memo = [[m+n+1 for i in range(n)] for j in range(m)]
return dp(m-1,n-1)
字典备忘录优化
class Solution:
def minDistance(self, word1: str, word2: str) -> int:
def dp(i,j):
if i < 0:
return j + 1
if j < 0:
return i + 1
if (i,j) in memo:
return memo[(i,j)]
if word1[i] == word2[j]:
memo[(i,j)] = dp(i-1,j-1)
else:
memo[(i,j)] = min(
dp(i-1,j) + 1,
dp(i,j-1) + 1,
dp(i-1,j-1) + 1
)
return memo[(i,j)]
m = len(word1)
n = len(word2)
memo = dict()
return dp(m-1,n-1)
dp数组优化
class Solution:
def minDistance(self, word1: str, word2: str) -> int:
m = len(word1)
n = len(word2)
#dp[i][j]表示word1[0..i]转换成word2[0..j]最少操作数,由于base case的index为-1,故整体右移一位
dp = [[0 for i in range(n+1)] for j in range(m+1)]
for j in range(1,n+1):
dp[0][j] = j
for i in range(1,m+1):
dp[i][0] = i
for i in range(1,m+1):
for j in range(1,n+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] + 1
)
return dp[m][n]