Leetcode 72. 编辑距离解题思路学习

1、带备忘录的递归

# 递归+备忘录
class Solution:
    def minDistance(self, s1, s2) -> int:
        memo = dict()
        # 定义:dp(i, j) 返回 s1[0..i] 和 s2[0..j] 的最小编辑距离
        def dp(i, j):
            # base case
            # 表示s1已从后向前遍历结束,s2此时索引为j,可将0~j索引之间的(j+1)个元素全部删除
            if i == -1: return j + 1
            # 原理同上
            if j == -1: return i + 1

            if (i, j) in memo:
                return memo[(i, j)]

            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)

2、动态规划(dp数组与方法一的函数定义不同)

# 动态规划
class Solution:
    def minDistance(self, s1, s2) -> int:
        m = len(s1)
        n = len(s2)
        # 定义:dp[i][j]存储s1[0...i-1],s2[0...j-1]的最小编辑距离
        dp = [[0] * (n + 1) for _ in range(m + 1)]
        # base case
        for i in range(1, m + 1):
            dp[i][0] = i
        for j in range(1, n + 1):
            dp[0][j] = j
        # 自底向上求解
        for i in range(1, m + 1):
            for j in range(1, n + 1):
                # 注意:此处和自顶向下的递归方法的条件不同,跟dp数组定义有关,i-1,j-1代表末尾索引
                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)
        # 存储着整个s1和s2的最小编辑距离
        return dp[m][n]

参考

https://www.bilibili.com/video/BV1uv411W73P/

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值