每天两道LeetCodeHard:(11)

167 阅读2分钟

72. Edit Distance

经典的字符串变换问题

题干:

Given two words word1 and word2, find the minimum number of operations required to convert word1 to word2.

You have the following 3 operations permitted on a word:

Insert a character
Delete a character
Replace a character

解释:

给两个字符串,长度不一定相同,让我们找到从字符串1变到字符串2的最小操作次数,每次操作可以插入,删除,或者替换

思考:

这个题也算是经典的字符串变换问题了,常规的思路是dfs或者是dp来递归解决这个问题。但是这个题的特殊点在于,按照什么原则选择插入位置,以及插入什么字符,如果直接暴力解的话复杂度就太高了。所以遇到这种问题,我们可以先举几个例子来找状态转移方程,首先dp代表需要操作的次数,因为字符串可能为空,所以我们dp[i][j]代表的是i-1和j-1上的字符的比较结果,从表格结果可以观察得出,增加,删除,修改依次可以表示为左,上,左上的结果,因此我们得到状态转移方程: dp[i][j] = / dp[i - 1][j - 1] if word1[i - 1] == word2[j - 1] \ min(dp[i - 1][j - 1], min(dp[i - 1][j], dp[i][j - 1])) + 1 else 初始边界值依次为i,因为一个字符串为空的话可以直接增加即可。最后的时间复杂度为44%

答案:

class Solution(object):
    def minDistance(self, word1, word2):
        n1=len(word1)
        n2=len(word2)
        dp=[[0]*(n2+1) for i in range(n1+1)]
        for i in range(n1+1):
            dp[i][0]=i
        for i in range(n2+1):
            dp[0][i]=i
        for i in range(1,n1+1):
            for j in range(1,n2+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], min(dp[i - 1][j], dp[i][j - 1])) + 1
        return dp[n1][n2]

答案补充:

字符串类型的动态规划一直是非常热门的dp题,需要熟练掌握几个关键点: 1,初始化边界值是i 2,迭代上界是len+1 3,根据s1[i-1],s2[j-1]来更新dp[i][j]的值 4,可以自己写一个表来快速寻找状态转移方程,之后再寻求解释。