day56|动态规划16-编辑距离问题

583. 两个字符串的删除操作

day56|动态规划16-编辑距离问题_第1张图片

  1. 明确dp数组的含义: dp[i][j] 以i-1为结尾的word1和以j-1为结尾的word2,为相同的最小操作次数
  2. 递归函数: if word1[i-1] == word1[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)
  3. 初始化dp数组
  4. 遍历方式
  5. 打印dp数组
class Solution:
    def minDistance(self, word1: str, word2: str) -> int:
        word1,word2 = list(word1),list(word2)
        row,col = len(word1)+1,len(word2)+1
        dp = [[0]*col for _ in range(row)]
        for i in range(row):
            dp[i][0] = i
        for j in range(col):
            dp[0][j] = j
        for i in range(1,row):
            for j in range(1,col):
            	# 做模拟删除的操作
                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]

其他思路: 找到最长公共子串,然后分别用两个元素对这个元素进行相减。

class Solution:
    def minDistance(self, word1: str, word2: str) -> int:
        # 求解两个字符串之间的最大公共子串
        word1,word2 = list(word1),list(word2)
        row,col = len(word1)+1,len(word2)+1
        dp = [[0]*col for _ in range(row)]
        result = 0
        for i in range(1,row):
            for j in range(1,col):
                if word1[i-1] == word2[j-1]:
                    dp[i][j] = dp[i-1][j-1] + 1
                else:
                    # 如果不相等,那么就删除一个字符找剩余的字符之间的公共关系
                    dp[i][j] = max(dp[i-1][j],dp[i][j-1])
                result = max(result,dp[i][j])
        return len(word1) + len(word2) - result * 2    

删除思路: 在删除的思路中,可以少一个字母观察其他字符串之间的关系。

72. 编辑距离

本质上就是对 两个字符串的删除操作问题的拓展,dp数据的含义可以更正为i-1的字符串到j-1的字符串需要操作几步可以完成变换。
在递推公式阶段如果两个字母是相同的那么就看前面字符串的处理次数即可,如果两个字母不相同,递推公式为dp[i][j] = min(dp[i][j-1]+1,dp[i-1][j]+1,dp[i-1][j-1]+1)

  • dp[i][j-1]+1:表示删除word2一项。
  • dp[i-1][j]+1:表示删除word1一项。
  • dp[i-1][j-1]+1:表示替换其中的一项,因为替换的操作要比删除两个的操作所用次数更少。
class Solution:
    def minDistance(self, word1: str, word2: str) -> int:
        word1 = list(word1)
        word2 = list(word2)
        row,col = len(word1)+1,len(word2)+1
        dp = [[0]*col for _ in range(row)]
        if len(word1) == 0 or len(word2) == 0:
            return max(len(word1),len(word2))
        for i in range(row):
            dp[i][0] = i
        for j in range(col):
            dp[0][j] = j
        for i in range(1,row):
            for j in range(1,col):
                if word1[i-1] == word2[j-1]:
                    dp[i][j] = dp[i-1][j-1]
                else:
                    dp[i][j] = min(dp[i][j-1]+1,dp[i-1][j]+1,dp[i-1][j-1]+1)
        return dp[-1][-1]

编辑距离总结篇

编辑距离主要是对上一步的字符串进行操作。关键在于考虑当前的元素是否相同。

你可能感兴趣的:(动态规划,算法)