描述
给定两个字符串 str1 和 str2 ,请你算出将 str1 转为 str2 的最少操作数。
你可以对字符串进行3种操作:
1.插入一个字符
2.删除一个字符
3.修改一个字符。
字符串长度满足 1≤n≤1000 ,保证字符串中只出现小写英文字母。
示例1
输入:
"nowcoder","new"
返回值:
6
说明:
"nowcoder"=>"newcoder"(将'o'替换为'e'),修改操作1次
"nowcoder"=>"new"(删除"coder"),删除操作5次
示例2
输入:
"intention","execution"
返回值:
5
说明:
一种方案为:
因为2个长度都是9,后面的4个后缀的长度都为"tion",于是从"inten"到"execu"逐个修改即可
示例3
输入:
"now","nowcoder"
返回值:
5
判断每个字符移动到对应的位置需要多少次,以此进行状态转移,最终结果就是 str1 的最后一个字符移动到 str2 的最后一个字符,需要移动的次数。
1、创建 dpMap,初始化第一行、第一列,其中 dpMap[0][0] = char1 == char2 ? 0 : 1,其余递增1
2、如果 char1 == char2,dp[yPos][xPos] = dp[yPos-1][xPos-1],如果不相同,那么dpMap 可以从 xPos-1 和 yPos-1 继承状态;因为存在 char1[xPos-1] == char2[yPos-1] 的情况,这时当前 char1 需要移动的次数减少一次,所以
dpMap[yPos][xPos] = Min(dpMap[yPos-1][xPos-1], Min(dpMap[yPos-1][xPos], dpMap[yPos][xPos-1])) + 1;
3、返回 dpMap[length2-1][length1-1]
public int editDistance (String str1, String str2) {
// write code here
int length1 = str1.length();
int length2 = str2.length();
int[][] dpMap = new int[length2][length1];
int xPos;
int yPos;
if (str1.charAt(0) == str2.charAt(0)) {
dpMap[0][0] = 0;
} else {
dpMap[0][0] = 1;
}
for (xPos = 1; xPos < length1; xPos++) {
dpMap[0][xPos] = dpMap[0][xPos-1] + 1;
}
for (yPos = 1; yPos < length2; yPos++) {
dpMap[yPos][0] = dpMap[yPos-1][0] + 1;
for (xPos = 1; xPos < length1; xPos++) {
if (str1.charAt(xPos) == str2.charAt(yPos)) {
dpMap[yPos][xPos] = dpMap[yPos-1][xPos-1];
} else {
dpMap[yPos][xPos] = Math.min(dpMap[yPos - 1][xPos], Math.min(dpMap[yPos][xPos - 1], dpMap[yPos - 1][xPos - 1])) + 1;
}
}
}
return dpMap[length2-1][length1-1];
}