题意
就一编辑距离的题,支持操作:insert, delete, remove,求从x到y的最小edit distance
思路
状态表示:d[i][j],从x[0, i]到y[0, j]的最小编辑距离
转移方程:
- x[i]==y[j]:当前位置不用编辑,直接转化为更小的子问题:d[i−1][j−1]
- x[i]≠y[j]:
- replace: d[i][j]=d[i−1,j−1]+1
- insert: d[i][j]=d[i,j−1]+1(我们在x[i+1]的位置上插入字符ch,使ch==y[j],这时候,还需求解的部分为xi和yj−1的编辑距离,转化为更小的子问题d[i,j−1]。
- delete: d[i][j]=d[i−1,j]+1(我们删去字符xi,这时候,还需求解的部分为xi−1和yj,转化为更小的子问题d[i−1.j]。
时间复杂度:O(n2)
空间复杂度:O(n2)
细节
- 边界情况,字符串是从0开始计数的, 因此边界情况为-1,并且要考虑越界。
- 写的记搜,因此初始化应该为INF而不是-1。
代码
const int maxn = 1005;
const int INF = 1e9 + 7;
int d[maxn][maxn];
class Solution {
public:
int dfs(string x, int i, string y, int j) {
if (i < 0 && j < 0) return 0;
if (i < 0) return j + 1;
if (j < 0) return i + 1;
if (d[i][j] != INF) return d[i][j];
if (x[i] == y[j]) return d[i][j] = dfs(x, i - 1, y, j - 1);
d[i][j] = dfs(x, i - 1, y, j - 1) + 1; //replace
d[i][j] = min(d[i][j], dfs(x, i - 1, y, j) + 1); //delete
return d[i][j] = min(d[i][j], dfs(x, i, y, j - 1) + 1); //insert
}
int minDistance(string word1, string word2) {
if (word1.empty()) return word2.size();
if (word2.empty()) return word1.size();
int m = word1.length(), n = word2.length();
for (int i = 0; i <= max(m, n); i++) {
for (int j = 0; j <= max(m, n); j++)
d[i][j] = INF;
}
int res = dfs(word1, m - 1, word2, n - 1);
return res;
}
};