-
题目描述
给定两个单词 word1 和 word2,计算出将 word1 转换成 word2 所使用的最少操作数 。
你可以对一个单词进行如下三种操作:
- 插入一个字符
- 删除一个字符
- 替换一个字符
-
思路
动态规划。
之前面试某公司遇到过这道题,由于将“替换一个字符”理解为“交换两个字符”,结果递推公式最终也没有推出来,还是得多沟通啊~~
言归正传,定义表示单词word1的前i个字符和单词word2的前j个字符的最少操作次数,即字符串与的最少操作次数。
依照动态规划的思路,如果我们已知了、和的值,怎么推出呢?
如果的话,那么其有三种可能性来达到最少操作次数:
- 等于,因为相同所以由扩展到并不需要多余的操作;
- 等于,因此相较于,多出来1个字符,因此插入或删除一个字符即可使其相等;
- 等于,原理同2;
如果的话,其也有三中情况:
- 等于,由于两个字符不同,则需要多1次的替换操作;
- 等于,同i和j相等的情况;
- 等于,同i和j相等的情况;
总结来看,
若,则
若,则
初始条件的话,显然
-
C++实现
class Solution {
public:
int minDistance(string word1, string word2) {
int size1 = word1.size();
int size2 = word2.size();
//由于size1和size2中必有1个0,所以size1+size2表示其中的非0值
if(size1*size2==0)return size1+size2;
vector<vector<int>> dp(size1+1,vector<int>(size2+1));
for(int i=0;i<size1+1;i++)
dp[i][0] = i;
for(int j = 0;j<size2+1;j++)
dp[0][j] = j;
for(int i=1;i<size1+1;i++){
for(int j=1;j<size2+1;j++){
if(word1[i-1]==word2[j-1])
dp[i][j] = min(min(dp[i-1][j]+1,dp[i][j-1]+1),dp[i-1][j-1]);
else
dp[i][j] = min(min(dp[i-1][j],dp[i][j-1]),dp[i-1][j-1])+1;
}
}
return dp[size1][size2];
}
};