leetcode(力扣) 72. 编辑距离 (动态规划)

本文详细介绍了如何使用动态规划解决编辑距离问题,通过具体实例展示了如何将一个字符串转换为另一个字符串所需的最少操作数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

给你两个单词 word1 和 word2, 请返回将 word1 转换成 word2 所使用的最少操作数 。
你可以对一个单词进行如下三种操作:
插入一个字符
删除一个字符
替换一个字符

示例 1:
输入:word1 = “horse”, word2 = “ros”
输出:3
解释:
horse -> rorse (将 ‘h’ 替换为 ‘r’)
rorse -> rose (删除 ‘r’)
rose -> ros (删除 ‘e’)

示例 2:
输入:word1 = “intention”, word2 = “execution”
输出:5
解释:
intention -> inention (删除 ‘t’)
inention -> enention (将 ‘i’ 替换为 ‘e’)
enention -> exention (将 ‘n’ 替换为 ‘x’)
exention -> exection (将 ‘n’ 替换为 ‘c’)
exection -> execution (插入 ‘u’)

思路分析

题目中说请返回将 word1 转换成 word2 所使用的最少操作数 。

题目中规定了将word1转换成word2。

并且规定了增删改三种操作。

现在假设有两个字符串 ,A:dog 。B:doge

让A和B相同,则可以:

  • A末尾添加一个e,变成doge。
  • B删除末尾的e,变成dog

可以发现上述两种操作是等价的,注意这里是指操作次数等价,而不是值变化之后的结果等价。

同理,例如有 A:dg和B:de ,有两种情况让他们变得等价。

  • 将A的末尾g变成e
  • 将B的末尾e变成g

综上,删除和增加元素是等价的,替换元素也是等价的。

所以问题变成:

  • 在A中删除一个字符
  • 在B中删除一个字符 (等价于在A中插入一个字符)
  • 替换A中的一个字符

老规矩,动态规划五步走;

1.确定dp数组下标含义:

dp[i][j] 表示 A字符串到下标i-1,B字符串到下标j-1 时的两个子串相等最小的编辑距离。

2.状态转移公式:

如果 A[i-1] == B[j-1] :
此时两字符串末尾项一样,不需要增删改,直接继承之前的最小编辑距离就行了。dp[i][j]=dp[i−1][j−1]

如果 A[i-1] != B[j-1] :

  • 删A的一个元素,那么就是以下标 i−2为结尾的 A与j−1 为结尾的 B的最近编辑距离 再加上一个操作。最少操作次数为 dp[i−1][j]+1

  • 删B的一个元素,那么就是以下标 i−1为结尾的 A与j−2 为结尾的 B的最近编辑距离 再加上一个操作。最少操作次数为 dp[i][j-1]+1

  • 替换掉A的末尾元素 也就是 A[i-2],使其等于B[j-2],那么就是以下标 i−2 为结尾的 word1 与 j−2 为结尾的 word2 的最近编辑距离 即 dp[i-1][j-1] 再加上一个替换元素的操作 , dp[i-1][j-1]+1.

  • 上面这三种操作都能让 子串A和B变得相同,那么取这三个中操作次数最小的即可。

完整代码

class Solution:
    def minDistance(self, word1: str, word2: str) -> int:

        dp = [[0] * (len(word2)+1) for _ in range(len(word1)+1)]


        for i in range(len(word1)+1):
            dp[i][0] = i
        for i in range(len(word2)+1):
            dp[0][i] = i

        for i in range(1,len(word1)+1):
            for j in range(1,len(word2)+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)
        print(dp)
        return dp[-1][-1]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

深度不学习!!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值