LeetCode.H72.编辑距离
题目:
题目大意:
如图所示。
数据范围:
如图所示
思路:
- 状态表示 :f(i, j) : 使 A(1, i) 变为 B(1, j) 的最短编辑距离。
- 状态转移方程:假设我们要求 A(1, i) 到 B(1, j) 的最短编辑距离 f(i, j)。那么需要分析 f(i, j) 这个状态可以由哪几个状态(这几个状态不重不漏)转移而来。根据题目定义,共有三种操作,及插、删、替换。那么 f(i, j) 可由上一个状态经过插、删或者替换而来,我们现在只对A进行操作。
- 插:及在 Ai 后面插入一个 Bj,由于我们可以进行 f(i, j - 1) 次操作使得 A(1, i) 变为 B(1, j - 1),所以再在 Ai 后面插入一个 Bj,即可将 B(1, j - 1)(这里的 B(1, j - 1) 其实是 A(1, i) 经过 f(i, j - 1) 次操作变来的)变为 B(1, j)。所以状态转移方程为: f(i, j) = f(i, j - 1) + 1
- 删:及将 Ai 删除,由于我们可以进行 f(i - 1, j) 次操作使得 A(1, i - 1) 变为 B(1, j),在进行 f(i - 1, j) 次操作后,A(1, i - 1) 已经变为了 B(1, j),对于 A(1, i), 我们直接将 Ai 删除,A(1, i )就变成了 B(1, j)。所以状态转移方程为:f(i, j) = f(i - 1, j) + 1
- 替换:及将 Ai 替换为 Bj,由于我们可以进行 f(i - 1, j - 1) 次操作使得 A(1, i - 1) 变为 B(1, j - 1),对于 A(1, i),当 Ai 与 Bj 相同时,无需进行替换,则状态转移方程为:f(i, j) = f(i - 1, j - 1)。如果 Ai 与 Bj 不同,那么就需要将 Ai 替换为 Bj,则状态转移方程为:f(i, j) = f(i - 1, j - 1) + 1
- f(i, j) 取三种操作的最小值即可。注意初始化状态。f(0, j) = j,及 A 为空字符时,变为 Bj 需要 j 次操作,同理,f(i, 0) = i。
代码:
class Solution {
public int minDistance(String word1, String word2) {
word1 = " " + word1;
word2 = " " + word2;
int m = word1.length(), n = word2.length();
int[][] f = new int[m][n];
for (int i = 0; i < m; i ++ ){
f[i][0] = i;
}
for (int i = 0; i < n; i ++ ){
f[0][i] = i;
}
for (int i = 1; i < m; i ++ ){
for (int j = 1; j < n; j ++ ){
f[i][j] = Math.min(f[i - 1][j], f[i][j - 1]) + 1;
if (word1.charAt(i) == word2.charAt(j)){
f[i][j] = Math.min(f[i][j], f[i - 1][j - 1]);
}else {
f[i][j] = Math.min(f[i][j], f[i - 1][j - 1] + 1);
}
}
}
return f[m - 1][n - 1];
}
}
public class Main {
public static void main(String[] args) {
Solution solution = new Solution();
String word1 = "horse", word2 = "ros";
System.out.println(solution.minDistance(word1, word2));
}
}
时空复杂度分析等:
-
时间复杂度 : O(m*n)
-
空间复杂度 : O(m*n)