给定两个单词 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')
解题思路:
辅助数组p[word1.length][word2.length],p[i][j]的值,表示word1[0~i]转换成word2[0~j]需要的最小操作数,那么有三种可能值:
- 由p[i][j-1]得来,p[i][j] = p[i][j-1] + 1
- 由p[i-1][j]得来,p[i][j] = p[i-1][j] + 1
- 由p[i-1][j-1]得来,若word1[i] == word2[j],则p[i][j] = p[i-1][j-1],否则p[i][j] = p[i-1][j-1] + 1
需要求得最小操作数,则取上述三个值中的最小值。
java代码:
class Solution {
public int minDistance(String word1, String word2) {
int m = word1.length(), n = word2.length();
if("".equals(word1) && "".equals(word2))
return 0;
else if("".equals(word1))
return n;
else if("".equals(word2))
return m;
int[][] p = new int[m][n];
p[0][0] = (word1.charAt(0) == word2.charAt(0) ? 0 : 1);
/**
* 计算辅助数组的第一行,p[0][i]
* 若word1[0] == word2[i] || p[0][i-1] == i-1(即word2的当前字符与word1[0]相同或者word2[0~i-1]中有字符与word1[0]相同,只需删除其余字符)
* 则p[0][i] = i;
* 否则p[0][i] = i+1(替换word2[0~i]中的一个字符,删除其他所有字符,即word2[0~i]中每个字符都需要修改)
* */
for(int i = 1; i < n; i++) {
p[0][i] = ((word1.charAt(0) == word2.charAt(i) || p[0][i-1] == i-1) ? i : i+1);
}
/**
* 计算辅助数组的第一列,p[i][0]
* 思路与计算p[0][i]相同
* */
for(int i = 1; i < m; i++) {
p[i][0] = ((word1.charAt(i) == word2.charAt(0) || p[i-1][0] == i-1) ? i : i+1);
}
for(int i = 1; i < m; i++) {
for(int j = 1; j < n; j++) {
int tmp = Math.min(p[i][j-1]+1, p[i-1][j-1] + (word1.charAt(i) == word2.charAt(j) ? 0 : 1));
p[i][j] = Math.min(p[i-1][j]+1, tmp);
}
}
return p[m-1][n-1];
}
}