编辑距离(72)——动态规划

题目

已知两个字符串word1word2,求从word1转化成word2最少需要几步。其中,每一步只能进行以下三个操作之一:

  1. 插入一个字符
  2. 删除一个字符
  3. 替换一个字符

分析

用动态规划的思路,用dp[i][j]表示word1的前i个字符转化为word2的前j个字符需要的操作次数。根据word1word2的最后一个字符是否相同,分为两种情况:

  1. word1[i] == word2[j]
    那么同时去掉最后一个字符,不影响结果,故dp[i][j] = dp[i-1][j-1]
  2. word1[i] != word2[j]
    可以用如下三种方法进行操作:
    1. 将word1转化为word2的前j-1个字符,再将word2的最后一个字符插入到word1末尾。即步骤为dp[i][j-1]+1
    2. 将word1的前i-1个字符转化为word2,再将word1的最后一个字符删除。即步骤为dp[i-1][j]+1
    3. 将word1的前i-1个字符转化为word2的前j-1个字符,再将word1的第i个字符替换为word2的第j个字符。即步骤为dp[i-1][j-1]+1
      dp[i][j]为三种方法的最小值,即dp[i][j] = min(dp[i][j-1]+1, dp[i-1][j]+1, dp[i-1][j-1]+1)

对于边界情况,i=0代表word1为空,故由word1插入j个字符可转化为word2,即dp[0][j] = j。同理,dp[i][0] = i

根据递推关系,这里不需要维护这个二维数组,只需要维护一行或者一列即可。

代码

class Solution(object):
    def minDistance(self, word1, word2):
        """
        :type word1: str
        :type word2: str
        :rtype: int
        """
        dp = [i for i in range(len(word2) + 1)]
        for i in range(1, len(word1)+1):
            ndp = [i]
            for j in range(1, len(dp)):
                if word1[i-1] == word2[j-1]:
                    ndp.append(dp[j-1])
                else:
                    ndp.append(min(dp[j-1]+1, dp[j]+1, ndp[j-1]+1))
            dp = ndp
        return dp[-1]
    原文作者:拔丝圣代
    原文地址: https://www.jianshu.com/p/5eba04971d60
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞