BM75 编辑距离(一)
描述
给定两个字符串 str1 和 str2 ,请你算出将 str1 转为 str2 的最少操作数。
你可以对字符串进行3种操作:
1.插入一个字符
2.删除一个字符
3.修改一个字符。
字符串长度满足 ,保证字符串中只出现小写英文字母。
示例1
输入:
返回值:
Java代码
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param str1 string字符串
* @param str2 string字符串
* @return int整型
*/
public int editDistance (String str1, String str2) {
int s1Len = str1.length();
int s2Len = str2.length();
// 如果有一个字符串长度等于0,那么最小变换次数即为 s1Len + s2Len;
if (s1Len == 0 || s2Len == 0) return s1Len + s2Len;
// 初始化dp数组,dp[i][j] 记录 str1 每一个字符 变成 str2的次数
int[][] dp = new int[s1Len + 1][s2Len +
1]; // 第一行第一列,辅助单元格
// 初始化第一行
// 可以理解为: 将一个空串,转变为str2字符串从0 ~ i的字符 所需要的次数
for (int i = 1; i < dp[0].length; i++) dp[0][i] = i;
// 初始化第一列
// 可以理解为: 将str1字符串从0 ~ i的字符 转变为 一个空串 所需要的次数
for (int i = 1; i < dp.length; i++) dp[i][0] = i;
// 下标从1开始遍历每一行
for (int i = 1; i < dp.length; i++) {
// 取出str1的 i索引字符
char strChar1 = str1.charAt(i - 1);
// 下标从1开始遍历每一列
for (int j = 1; j < dp[0].length; j++) {
// 取出str2的 j索引字符
char strChar2 = str2.charAt(j - 1);
// 如果相等,那么只需要取出左斜方单元格记录的次数即可
if (strChar1 == strChar2) {
dp[i][j] = dp[i - 1][j - 1];
} else {
// 如果不相等,取出左斜方,上方,左方的值,取最小后 + 1 即为当前 0 ~ i索引的str1字符串变换成 0 ~ j索引的str2字符串所需要的次数
int i1 = dp[i - 1][j - 1];
int i2 = dp[i][j - 1];
int i3 = dp[i - 1][j];
dp[i][j] = Math.min(i3, Math.min(i1, i2)) + 1;
}
}
}
// 循环结束,dp表格最后一个单元格记录的值,即为解
return dp[s1Len][s2Len];
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
import java.util.*;
public class Solution {
int[][] memo; //备忘录,记录递归中间结果
public int editDistance (String word1, String word2) {
int len1 = word1.length();
int len2 = word2.length();
memo = new int[len1][len2];
//初始化备忘录
for (int[] row : memo) {
Arrays.fill(row, -1);
}
//用二个指针从二个字符串末尾开始向前遍历
return dp(word1, word2, len1- 1, len2 - 1);
}
//dp(i,j)表示以i的字符串s1变为以j结尾的s2的最少操作数
int dp(String s1, String s2, int i, int j) {
//如果s1遍历结束,则s1添加s2的剩余字符
if (i == -1) return j + 1;
//如果s2遍历结束,则s1删掉s2的剩余字符
if (j == -1) return i + 1;
//如果计算过则直接返回
if (memo[i][j] != -1) {
return memo[i][j];
}
//如果当前位置相等,则什么都不做
if (s1.charAt(i) == s2.charAt(j)) {
memo[i][j] = dp(s1, s2, i - 1, j - 1);
} else { //如果不等,则进行增、删、换
//增加:i比不变,j前移。删除:i前移,j不变
int temp = Math.min(dp(s1, s2, i, j - 1), dp(s1, s2, i - 1, j)) + 1;
//替换;i和j都前移
memo[i][j] = Math.min(temp, dp(s1, s2, i - 1, j - 1) + 1);
}
return memo[i][j];
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.