72 编辑距离
一、题目
给你两个单词 word1 和 word2, 请返回将 word1 转换成 word2 所使用的最少操作数 。
你可以对一个单词进行如下三种操作:
- 插入一个字符
- 删除一个字符
- 替换一个字符

二、题解
思路:
dp[i][j]表示:把 word1 的前 i 个字符,转换成 word2 的前 j 个字符,所需要的最少操作次数。如果当前字符相同,就继承左上角状态;如果不同,就从删除、插入、替换三种操作中选最小值再加一。
状态初始化:
- 如果
word2是空字符串,那么word1只能一直删除:dp[i][0] = i - 如果
word1是空字符串,那么只能一直插入:dp[0][j] = j
状态转移:
-
情况一:两个字符相同 如果当前字符一样,不需要操作:
dp[i][j] = dp[i - 1][j - 1]; -
情况二:两个字符不同 如果当前字符不同,有三种操作:
- 删除:删除
word1当前字符:dp[i - 1][j] + 1 - 插入:向
word1插入一个字符:dp[i][j - 1] + 1 - 替换:把
word1当前字符替换成word2当前字符:dp[i - 1][j - 1] + 1所以取三者最小值:dp[i][j] = Math.min(Math.min(dp[i - 1][j], dp[i][j - 1]), dp[i - 1][j - 1]) + 1;
- 删除:删除
class Solution {
public int minDistance(String word1, String word2) {
int m = word1.length();
int n = word2.length();
// dp[i][j] 表示 word1 前 i 个字符转换成 word2 前 j 个字符的最少操作数
int[][] dp = new int[m + 1][n + 1];
// 初始化第一列:word1 前 i 个字符转换成空串,只能删除
for (int i = 0; i <= m; i++) {
dp[i][0] = i;
}
// 初始化第一行:空串转换成 word2 前 j 个字符,只能插入
for (int j = 0; j <= n; j++) {
dp[0][j] = j;
}
// 填表
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
char c1 = word1.charAt(i - 1);
char c2 = word2.charAt(j - 1);
// 如果当前字符相同,不需要操作
if (c1 == c2) {
dp[i][j] = dp[i - 1][j - 1];
} else {
// 当前字符不同,可以删除、插入、替换,取最小值
dp[i][j] = Math.min(
Math.min(dp[i - 1][j], dp[i][j - 1]),
dp[i - 1][j - 1]
) + 1;
}
}
}
return dp[m][n];
}
}
时间复杂度:O(m * n) 空间复杂度:O(m * n)
评论