很早之前就看到这道题了,当时觉得毫无头绪就没有去做,今天终于做到了这道题,写一下题解
题目:给定两个单词 word1 和 word2,计算出将 word1 转换成 word2 所使用的最少操作数 。
你可以对一个单词进行如下三种操作:
- 插入一个字符
- 删除一个字符
- 替换一个字符
示例:输入: word1 = "horse", word2 = "ros"
输出: 3
解释:
horse -> rorse (将 'h' 替换为 'r')
rorse -> rose (删除 'r')
rose -> ros (删除 'e')
我们用一个数组dp[i][j]来表示word1的前i位转换成word2的前j位最小操作数。
最终我们需要的答案就是dp[n][m]的值,也就是word1的前n位转换成word2的前m位所需最小操作数
(n和m分别为word1和word2的长度)
然后初始化该数组(就是i==0的时候和j==0的时候)
i==0 && j!=0 的时候表示把一个空字符串转换成word2的前j位,最小操作数也就是word2的长度了。
i!=0 && j==0 的时候表示把一个空字符串转换成word1的前i位,最小操作数也就是word1的长度了。
其他的暂且为0
r | o | s | ||
---|---|---|---|---|
0 | 1 | 2 | 3 | |
h | 1 | 0 | 0 | 0 |
o | 2 | 0 | 0 | 0 |
r | 3 | 0 | 0 | 0 |
s | 4 | 0 | 0 | 0 |
e | 5 | 0 | 0 | 0 |
我们从i==1和j==1开始遍历数组,对于当前的dp[i][j],我们有三种操作
插入:dp[i][j] = dp[i][j-1] + 1 //word1的i位变成word2的j-1位然后插入一个字符,加1操作数
删除:dp[i][j] = dp[i-1][j] + 1 //word1的i-1位变成word2的j位然后删除一个字符,加1操作数
替换:dp[i][j] = dp[i-1][j-1] + (word[i] != word[j]) //如果word[i] == word[j] 那么这个表达式为0,也就是说对于当前位置,我们不用做任何操作,因为它们相等,所以加0. 如果不相等,这个表达式为1,就代表要替换当前字符,加1操作数。
对于这三种操作取最小值作为dp[i][j],保证dp[i][j]为最小值
最后的表格如下:
最后答案:dp[n][m]=3
代码:
class Solution {
public:
int minDistance(string word1, string word2) {
int n=word1.size(),m=word2.size();
int dp[n+1][m+1]={0};
for(int i=0;i<n+1;++i)dp[i][0]=i;
for(int i=0;i<m+1;++i)dp[0][i]=i;
for(int i=1; i<n+1;++i){
for(int j=1; j<m+1; ++j){
dp[i][j] = dp[i-1][j-1] + (word1[i-1] != word2[j-1]);
dp[i][j] = min(dp[i][j-1] + 1 , dp[i][j]);
dp[i][j] = min(dp[i-1][j] + 1, dp[i][j]);
}
}
return dp[n][m];
}
};
有什么错误还请大佬指出!