Edit Distance

传送门: edit-distance

这题是比较简单的 DP 题, 状态 D[i][j] 为子串 word1[..=i] 到 word2[..=j] 的最小编辑距离, 状态转移为

1
D[i][j] = min(D[i-1][j], D[i][j-1], D[i-1][j-1]) + 1

解释一下, 从 D[i][j-1] 到 D[i][j] 相当于插入操作, D[i-1][j] 到 D[i][j] 相当于删除操作, D[i-1][j-1] 到 D[i][j] 就相当于替换操作, 考虑到 i 和 j 位置的字符相同时不需要替换, 所以最后的状态转移为

1
D[i][j] = min(D[i-1][j]+1, D[i][j-1]+1, D[i-1][j-1] + word1[i] != word2[j])

然后是我的实现, 加了辅助空串(PS: word1 到 word2 的相互编辑距离是相等的, 所以遍历方向任意

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
impl Solution {
pub fn min_distance(word1: String, word2: String) -> i32 {
let n = word1.len() + 1;
let m = word2.len() + 1;
let mut d = Vec::new();
d.resize(n * m, 0);
for i in 0..n {
d[i * m] = i as i32;
}
for j in 0..m {
d[j] = j as i32;
}
let word1 = word1.as_bytes();
let word2 = word2.as_bytes();
for i in 1..n {
for j in 1..m {
d[i * m + j] = (d[i * m + j - 1] + 1)
.min(d[(i - 1) * m + j] + 1)
.min(d[(i - 1) * m + j - 1] + (word1[i - 1] != word2[j - 1]) as i32);
}
}
d[n * m - 1]
}
}