题目 编辑距离
给定两个单词 word1 和 word2,计算出将 word1 转换成 word2 所使用的最少操作数 。
你可以对一个单词进行如下三种操作:
插入一个字符
删除一个字符
替换一个字符
示例
输入: word1 = "intention", word2 = "execution"
输出: 5
解释:
intention -> inention (删除 't')
inention -> enention (将 'i' 替换为 'e')
enention -> exention (将 'n' 替换为 'x')
exention -> exection (将 'n' 替换为 'c')
exection -> execution (插入 'u')
题解
知识点 用动态规划解题,
用一个solve[word2len][word1len]的矩阵存储字符串之间的编辑距离。
为了避免边界问题solve的维度为 word1 length +1 用于存储边界信息
// T=min{solve[j-1][i-1],solve[j][i-1],solve[j-1][i]} 来自同层或则上一层前一个最小值(删|改),或则来自同一个位置添加一个(增)
// solve[j][i]=word2[j]==word1[i]? T:T+1;
注意 可以进行增删替换三种操作,之前忘了增这个操作,踩了坑o(╯□╰)o。增的时候就是在上一层同一个位置+1
进一步的优化,可以用一个滚动的二维数组solve[2][word1len]来替代solve[word2len][word1len] ,减少空间存储。
class Solution {
// T=min{solve[j-1][i-1],solve[j][i-1],solve[j-1][i]} 来自同层或则上一层前一个最小值(删|改),或则来自同一个位置添加一个(增)
// solve[j][i]=w[j]==w[i]? T:T+1;
public int minDistance(String word1, String word2) {
//dp
int len1 = word1.length();
int len2 = word2.length();
int minTmp;
int maxLen;
if(len1>=len2){//每次保证word1的长度最长
maxLen=len1;
}else{
maxLen=len1;
len1=len2;
len2=maxLen;
maxLen=len1;
String tmp=word1;
word1=word2;
word2=tmp;
}
int solve[][] = new int[len2+1][maxLen+1];
for(int i =0; i< maxLen+1; i++){//赋初值
solve[0][i]=i;
}
for(int i =0; i< len2+1; i++){//赋初值
solve[i][0]=i;
}
for(int j=1; j < len2+1; j++){ //j表是word2第几个元素,(j-1)%2 表是上一层 j%2 表是这一层
for(int i = 1; i < maxLen+1; i++){
if(word1.charAt(i-1) == word2.charAt(j-1)){
solve[j][i]=solve[j-1][i-1];
}else{
minTmp= solve[j-1][i-1] >solve[j][i-1] ?solve[j][i-1]:solve[j-1][i-1];
solve[j][i]=1 + (solve[j-1][i] > minTmp ? minTmp:solve[j-1][i]);
}
}
}
return len2==0?len1:solve[len2][len1];
}
}