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

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

在这里插入图片描述

  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]

编辑距离总结篇

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值