题目:
Given two words word1 and word2, find the minimum number of operations required to convert word1 to word2.
You have the following 3 operations permitted on a word:
- Insert a character
- Delete a character
- Replace a character
Example 1:
Input: word1 = "horse", word2 = "ros" Output: 3 Explanation: horse -> rorse (replace 'h' with 'r') rorse -> rose (remove 'r') rose -> ros (remove 'e')
Example 2:
Input: word1 = "intention", word2 = "execution" Output: 5 Explanation: intention -> inention (remove 't') inention -> enention (replace 'i' with 'e') enention -> exention (replace 'n' with 'x') exention -> exection (replace 'n' with 'c') exection -> execution (insert 'u')
描述:
给出两个字符串a和b,只能执行三种操作:
1,插入一个字符
2,删除一个字符
3,替换一个字符
问将a转化为b,最少需要多少次操作
分析:
求编辑距离...
用DP的思想递推,dp[i][j]表示第一个串(设为a)的i之前的子串和第二个串(设为b)j之前的子串的编辑距离,
dp[0][0]只能取0或1,
对于dp[i][j]
如果 a[i] == b[j] 那么 dp[i][j] = min(dp[i - 1] + 1, dp[j - 1] + 1, dp[i][j]),
如果 a[i] != b[j] 那么 dp[i][j] = min(dp[i - 1] + 1, dp[j - 1] + 1, dp[i][j] + 1),
另外注意dp的值不能小于两个串的差值
代码:(时间复杂度 O(n^m),空间复杂度 O(m,其中n和m分别为两个串的长度)
class Solution {
public:
int minDistance(string word1, string word2) {
int lena = word1.size(), lenb = word2.size();
if (lena == 0 || lenb == 0) {
return max(lena, lenb);
}
vector<int> previous;
vector<int> current;
current.push_back(word1[0] != word2[0]);
for (int i = 1; i < lenb; ++ i) {
int temp = current.back() + (word1[0] != word2[i]);
temp = max(temp, abs(i));
current.push_back(temp);
}
previous = current;
for (int i = 1; i < lena; ++ i) {
current.clear();
int temp = previous[0] + (word1[i] != word2[0]);
temp = max(temp, abs(i));
current.push_back(temp);
for (int j = 1; j < lenb; ++ j) {
int temp = 1 + min(previous[j], current[j - 1]);
if (word1[i] == word2[j]) {//相同
temp = min(temp, previous[j - 1]);
} else {
temp = min(temp, 1 + previous[j - 1]);
}
current.push_back(temp);
}
previous = current;
}
return previous[lenb - 1];
}
};