Leetcode 72. Edit Distance 编辑距离
72. Edit Distance 编辑距离
题目描述
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')
解答
这道题思路是典型的DP问题,令dp[i][j] 为word1的前i个字符转换成word2的前j个字符需要多少次操作。
若word1[i] = word2[j]的话,则dp[i][j] = dp[i - 1][j - 1]
否则,由题意知,从word1变成word2有三种选择:
- 插入一个字符,插入的是word2[j - 1],则 dp[i][j] = dp[i][j - 1] + 1
- 删除一个字符,删除的是word1[i - 1], 则 dp[i][j] = dp[i - 1][j] + 1
- 替换一个字符,则 dp[i][j] = dp[i - 1][j - 1] + 1
选择如上三种操作的最小值即是dp[i][j]。
代码
class Solution {
public:
int minDistance(string word1, string word2) {
int m = word1.size(), n = word2.size();
vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0));
for (int i = 1; i <= m; i ++) {
dp[i][0] = i;
}
for (int j = 1; j <= n; j ++) {
dp[0][j] = j;
}
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (word1[i - 1] == word2[j - 1]) {
dp[i][j] = dp[i - 1][j - 1];
}
else {
dp[i][j] = min(dp[i - 1][j - 1], min(dp[i][j - 1], dp[i - 1][j])) + 1; }
}
}
return dp[m][n];
}
};
考虑到我们在计算dp[i][j] 的时候只需要dp[i - 1][j - 1],dp[i][j - 1] 和dp[i - 1][j] 我们可以把二维的DP数组降到一维,具体代码如下。
class Solution {
public:
int minDistance(string word1, string word2) {
int m = word1.size(), n = word2.size();
int pre;
vector<int > cur(n + 1, 0);
for (int j = 1; j <= n; j++) {
cur[j] = j;
}
for (int i = 1; i <= m; i++) {
pre = cur[0];
cur[0] = i;
for (int j = 1; j <= n; j++) {
int temp = cur[j];
if (word1[i - 1] == word2[j - 1]) {
cur[j] = pre;
}
else {
cur[j] = min(cur[j], min(pre, cur[j - 1])) + 1;
}
pre = temp;
}
}
return cur[n];
}
};