LeetCode: Edit Distance
题目
https://oj.leetcode.com/problems/edit-distance/
分析
一开始没有思路,看了一些大神的解法以后才明白如何用动态规划的思路来解决这道题。
- 数据结构
创建一个二维数组res[][],其中res[i][j]用来代表word1[0 : i-1]和word2[0 : j-1]的EditDistance。
- 递归关系
考虑word1[i] == word2[j]的情况, 直接匹配即可,res[i][j] = res[i-1][j-1];
考虑word1[i] == word2[j]的情况,这种情况下分为以下多种情况来处理,然后取其中的最小值即可
A. 用replace来处理,res[i][j] = res[i-1][j-1] + 1。这个应该很好理解,比如"abc1"和"abc2"两个字符串,res["abc1"]["abc2"] = res["abc"]["abc"] + 1。
B. 用insert来处理,res[i][j] = res[i][j-1] + 1; 举个例子,还是"abc1"和"abc2"两个字符串,res["abc1"]["abc2"] = res["abc1"]["abc"] + 1;
C. 用delete来处理,res[i][j] = res[i-1][j] + 1; 举个例子,还是"abc1"和"abc2"两个字符串,res["abc1"]["abc2"] = res["abc"]["abc2"] + 1;
- 数据结构的初始化
因为在递归关系中用到了res[i-1][j-1],所以数据结构中的数据必然要先初始化才行,
res[i][0] = i; 代表 ""和"abc2"的EditDistance为4
res[0][i] = i; 代表 "abc1"和""的EditDistance为4
- 其他
在2. 递归关系中,还少考虑了一种情况,只不过为了理解起见一开始没有说,
当res[i] == res[j]时, res[i][j] 有时不能直接等于res[i-1][j-1],因为有可能用insert/delete处理的EditDistance比直接匹配的EditDistance更小,
所以res[i][j] = min(直接匹配,insert处理, delete处理), 即 res[i][j] = min(res[i-1][j-1], res[i-1][j] + 1, res[i][j-1] + 1);
代码
class Solution
{
public:
int minDistance(string word1, string word2)
{
int m = word1.size();
int n = word2.size();
vector<vector<int>> res(m + 1, vector<int>(n + 1));
for (int i = 0; i <= m; i++)
res[i][0] = i;
for (int i = 0; i <= n; i++)
res[0][i] = i;
for (int i = 1; i <= m; i++)
for (int j = 1; j <= n; j++)
{
res[i][j] = min(res[i-1][j] + 1, res[i][j-1] + 1);
if (word1[i-1] == word2[j-1])
res[i][j] = min(res[i][j], res[i-1][j-1]);
else
res[i][j] = min(res[i-1][j-1] + 1, res[i][j]);
}
return res[m][n];
}
};
参考
http://yucoding.blogspot.com/2013/09/leetcode-question-29-edit-distance.html
http://fisherlei.blogspot.com/2012/12/leetcode-edit-distance.html
本文章迁移自http://blog.csdn.net/timberwolf_2012/article/details/40894107