编辑距离
给你两个单词 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')
提示:
0 <= word1.length, word2.length <= 500
word1 和 word2 由小写英文字母组成
题解思路:
动态规划,状态转移方程比较难想。经典的编辑距离算法。定理一:如果其中一个字符串是空串,那么编辑距离是另一个字符串的长度。比如空串“”和“ro”的编辑距离是2(做两次“插入”操作)。再比如"hor"和空串“”的编辑距离是3(做三次“删除”操作)。
定理二:当i>0,j>0时(即两个串都不空时)dp[i][j]=min(dp[i-1][j]+1,dp[i][j-1]+1,dp[i-1][j-1]+int(word1[i]!=word2[j]))。
啥意思呢?举个例子,word1 = "abcde", word2 = "fgh",我们现在算这俩字符串的编辑距离,就是找从word1,最少多少步,能变成word2?那就有三种方式:
知道"abcd"变成"fgh"多少步(假设X步),那么从"abcde"到"fgh"就是"abcde"->"abcd"->"fgh"。(一次删除,加X步,总共X+1步)
知道"abcde"变成“fg”多少步(假设Y步),那么从"abcde"到"fgh"就是"abcde"->"fg"->"fgh"。(先Y步,再一次添加,加X步,总共Y+1步)
知道"abcd"变成“fg”多少步(假设Z步),那么从"abcde"到"fgh"就是"abcde"->"fge"->"fgh"。(先不管最后一个字符,把前面的先变好,用了Z步,然后把最后一个字符给替换了。这里如果最后一个字符碰巧就一样,那就不用替换,省了一步)
代码:
class Solution {
public int minDistance(String word1, String word2) {
int len1 =word1.length();
int len2 =word2.length();
int[][] dp =new int[len1+1][len2+1];
//dp[i][j]是指word1的前i的字符转化成word2的前j个字符所需要的最小步数
for(int i=0;i<len1+1;i++){
dp[i][0]=i;
}
for(int j=0;j<len2+1;j++){
dp[0][j]=j;
}
for(int i=1;i<len1+1;i++){
for(int j=1;j<len2+1;j++){
int equalNum=word1.charAt(i-1)==word2.charAt(j-1)?0:1;
dp[i][j]=Math.min(Math.min(dp[i-1][j]+1,dp[i][j-1]+1),dp[i-1][j-1]+equalNum);
}
}
return dp[len1][len2];
}
}