首页 > 代码库 > Edit Distance
Edit Distance
一、 题目
这道题是求一个字符串编辑成为另一个字符串的最少操作数,只有三种操作包括添加,删除或者替换一个字符。
二、 分析
这其实是一道二维动态规划的题目,维护的变量dp[i][j]表示的是word1的前i个字符和word2的前j个字符编辑的最少操作数是多少。我们分两种情况来讨论:
1)如果word1[i-1]=word2[j-1],也就是当前两个字符相同,那么也就是不需要编辑,则我们容易得到dp[i][j]=dp[i-1][j-1]
2)如果word1[i-1]!=word2[j-1],那么我们就需要考虑三种操作,如果是插入word1,那么dp[i][j]=dp[i-1][j]+1,也就是取word1前i-1个字符和word2前j个字符的最好结果,然后添加一个插入操作;如果是插入word2,那么dp[i][j]=dp[i][j-1]+1,同上面一种操作;如果是替换操作,那么类似于上面第一种情况,但是要加一个替换操作(因为word1[i-1]和word2[j-1]不相等),所以递推式是dp[i][j]=dp[i-1][j-1]+1。
上面列举的情况包含了所有可能性,在网上看到有人可能会说为什么没有删除操作,其实这里添加一个插入操作永远能得到与一个删除操作相同的效果,所以删除不会使最少操作数变得更好,因此如果我们是正向考虑,则不需要删除操作。取上面几种情况最小的操作数,即为第二种情况的结果,即dp[i][j] = min(dp[i-1][j], res[i][j-1], dp[i-1][j-1])+1。
分析下复杂度,算法时间上就是两层循环,所以时间复杂度是O(m*n)。
class Solution { public: int minDistance(string word1, string word2) { int len1 = word1.size(); int len2 = word2.size(); if(len1 == 0) return len2; if(len2 == 0) return len1; int dp[len1+1][len2+2]; //memset(dp,0,len1*len2*dp[0][0]); for(int i=0;i<len1;i++) for(int j=0;j<len2;j++) dp[i][j] = 0; for(int i=0; i<=len1; i++) dp[i][0] = i; for(int j=0; j<=len2; j++) dp[0][j] = j; for(int i=1; i<=len1; i++){ for(int j=1;j<=len2; j++){ if(word1[i-1] == word2[j-1]) dp[i][j] = dp[i-1][j-1]; else dp[i][j] = 1 + Min(dp[i-1][j-1],Min(dp[i-1][j],dp[i][j-1])); } } return dp[len1][len2]; } int Min(int a, int b) { if(a>b) return b; else return a; } };
Edit Distance