编辑距离算是一个比较经典的问题,可以用于常见的拼写纠错。
给定两个单词 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')
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/edit-distance
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
对于两个字符串,我们从右到左进行比较:
当a[i]==b[i]那么我们需要做任何操作,操作次数和a[i-1]与b[i-1]的操作次数相同。
如果不相等,那么我们有三种选择:第一种,删除a的当前元素(操作次数1)+以a[i-1]结尾串和以b[i]结尾串的操作次数;第二种,在当前位置插入一个元素,使得其与b[i]相等(操作次数1)+以a[i]结尾串与以b[i-1]结尾串的操作次数;第三种情况,替换a[i]使其等于b[i](操作次数1)+以a[i-1]结尾串和以b[i-1]结尾串的操作次数。在这三种情况里,选择一个操作次数最少的。
当其中一个串空是,最短的操作次数就是另外一个串的长度。
class Solution {
public:
//递归超时
int MinDistance(string word1,string word2,int w1,int w2)
{
if(w1==0)
return w2;
else if(w2==0)
return w1;
else if(word1[w1-1]==word2[w2-1])
return MinDistance(word1,word2,w1-1,w2-1);
return 1+min(MinDistance(word1,word2,w1,w2-1),min(MinDistance(word1,word2,w1-1,w2),MinDistance(word1,word2,w1-1,w2-1)));
}
int minDistance(string word1, string word2) {
int w1=word1.size();
int w2=word2.size();
return MinDistance(word1,word2,w1,w2);
}
};
class Solution {
public:
//N*N的空间 N*N的时间复杂度
int minDistance(string word1, string word2) {
int w1=word1.size();
int w2=word2.size();
vector>dp(w1+1,vector(w2+1,0));
//dp[i][j]:表示长度为i的字符串1与长度为j的字符串2需要的操作次数
for(int i=0;i<=w1;++i)
{
for(int j=0;j<=w2;++j)
{
if(j==0)//如果str2为空串 把str1全部删除
dp[i][j]=i;
else if(i==0)//同理s1为空串
dp[i][j]=j;
else 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],min(dp[i][j-1],dp[i-1][j-1]));
}
}
}
return dp[w1][w2];
}
};
class Solution {
public:
//N*N的空间 N*N的时间复杂度
int minDistance(string word1, string word2) {
int w1=word1.size();
int w2=word2.size();
vector>dp(2,vector(w1+1,0));
//其实可以发现我们每次更新的时候 状态只和其前一行有关系
//我们以str1作为基准 来比如
for(int i=0;i<=w1;++i)
{
dp[0][i]=i;//假设str2为空
}
//i%2的作用就是取交替下标0,1
for(int i=1;i<=w2;++i)
{
for(int j=0;j<=w1;++j)
{
if(j==0)//如果str1为空 i%2=0去当前位置p[0]
dp[i%2][j]=i;
else if(word1[j-1]==word2[i-1])
dp[i%2][j]=dp[(i-1)%2][j-1];//和i-1,j-1一样
else
{
dp[i%2][j]=1+min(dp[(i-1)%2][j],min(dp[i%2][j-1],dp[(i-1)%2][j-1]));
}
}
}
return dp[w2%2][w1];
}
};