Leetcode算法——72、编辑距离(edit distance)

76 篇文章 1 订阅

给定两个单词 word1 和 word2,找到将 word1 转化为 word2 所需的最少操作步数。(这个步数称为两个单词的编辑距离)

对一个单词可以执行以下三种操作:
1、插入一个字符
2、删除一个字符
3、替换一个字符

示例:

Example 1:
Input: word1 = "horse", word2 = "ros"
Output: 3
Explanation: 
horse -> rorse (replace 'h' with 'r')
rorse -> rose (remove 'r')
rose -> ros (remove 'e')

Example 2:
Input: word1 = "intention", word2 = "execution"
Output: 5
Explanation: 
intention -> inention (remove 't')
inention -> enention (replace 'i' with 'e')
enention -> exention (replace 'n' with 'x')
exention -> exection (replace 'n' with 'c')
exection -> execution (insert 'u')

思路

动态规划

我们要求的两个字符串的编辑距离,可以从两个字符串的子串的编辑距离得到。

D ( i , j ) D(i,j) D(i,j) 为 word1 前i个字符和 word2 前j个字符的编辑距离。

那么有递推关系式:

D ( i , j ) = m i n { D ( i − 1 , j ) + 1 D ( i , j − 1 ) + 1 D ( i − 1 , j − 1 ) + { 0 , w o r d 1 ( i ) = = w o r d 2 ( j ) 1 , e l s e D(i,j)=min\begin{cases} D(i-1,j) + 1\\ D(i,j-1) + 1\\ D(i-1,j-1) +\begin{cases} 0, &word1(i) == word2(j)\\ 1, &else \end{cases} \end{cases} D(i,j)=minD(i1,j)+1D(i,j1)+1D(i1,j1)+{0,1,word1(i)==word2(j)else

我们要求的是 D ( m , n ) D(m,n) D(m,n),其中 m 和 n 分别为 word1 和 word2 的长度。

这样,最终会将 D 构成一个 m ∗ n m*n mn的二维矩阵,从左上角开始,从上到下从左到右开始遍历,最后到右下角为止。右下角的值即为所求。

注意:在遍历之前,需要先对矩阵进行初始化:
{ D ( i , 0 ) = i , i = 1 , . . . , m D ( 0 , j ) = j , j = 1 , . . . , n \begin{cases} D(i,0)=i,&i=1,...,m\\ D(0,j)=j,&j=1,...,n \end{cases} {D(i,0)=i,D(0,j)=j,i=1,...,mj=1,...,n
即:一个非空字符串和一个空字符串的编辑长度,就等于非空字符串的长度。

本算法时间复杂度为 O ( m n ) O(mn) O(mn)

python实现

def minDistance(word1, word2):
    """
    :type word1: str
    :type word2: str
    :rtype: int
    动态规划。
    """
    m = len(word1)
    n = len(word2)
    # 初始化,D(i,0)=i, D(0,j)=j
    D = [[0] * (n+1) for _ in range(m+1)]
    D[0] = [i for i in range(n+1)]
    for i in range(m+1):
        D[i][0] = i
    # 迭代
    for i in range(1,m+1):
        for j in range(1,n+1):
            tmp1 = min(D[i-1][j], D[i][j-1]) + 1
            tmp2 = D[i-1][j-1] + (0 if word1[i-1] == word2[j-1] else 1)
            D[i][j] = min(tmp1, tmp2)
    return D[m][n]

if '__main__' == __name__:
    word1 = "intention"
    word2 = ""
    print(minDistance(word1, word2))
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值