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')
方法1: dynamic programming
官方题解:https://leetcode.com/problems/edit-distance/solution/
basketking: https://www.youtube.com/watch?v=Uv9dNpHlSY4
思路:
- 建立二维dp数组(m + 1, n + 1),其含义为:edit distance between s[0, i] and t[0, j], inclusive。
- initialization:0 行和0 列表示,如果其中一个字符串为空,需要edit多少次使其相等?所以是另一个字符串的长度。因为最后要取最小值,将所有其他项统一设为INT_MAX.
- transfer: 分为两种情况
3.1. s[i] = t[j]: 那么要比较三个转移个source,以12b 和 ab来举栗,从上转移:也就是使12和ab相等的distance,再加上删除12b中的b;从左转移:也就是使12b和a相等的distance,再加上删除ab中的b;从左上转移:也就是使12和a相等后,由于b = b直接转移进dp[i][j]。
3.2. s[i] != t[j]: 也要比较三个转移个source,唯一不同就是从左上转移同样要进行+1次修改,因为当前位置也不等。
4.返回dp.back().back()。
易错点
- 初始化。
- transfer function 需要分两种情况。
class Solution {
public:
int minDistance(string word1, string word2) {
// state : dp[i][j]: distance between s[0, i] and t[0, j], inclusive
vector<vector<int>> dp(word1.size() + 1, vector<int>(word2.size() + 1, INT_MAX));
// initialization
for (int i = 0; i < dp.size(); i++) {
dp[i][0] = i;
}
for (int j = 0; j < dp[0].size(); j++) {
dp[0][j] = j;
}
// transfer:
// if [i] == [j], dp[i][j] = min(dp[i][j - 1] + 1, dp[i - 1][j] + 1, dp[i - 1][j - 1]);
// if [i] != [j], dp[i][j] = min(dp[i][j - 1], dp[i - 1][j], dp[i - 1][j - 1]) + 1;
for (int i = 1; i < dp.size(); i++) {
for (int j = 1; j < dp[0].size(); j++) {
if (word1[i - 1] == word2[j - 1]){
dp[i][j] = min(dp[i][j - 1] + 1, min(dp[i - 1][j] + 1, dp[i - 1][j - 1]));
}
else {
dp[i][j] = min(dp[i][j - 1], min(dp[i - 1][j], dp[i - 1][j - 1])) + 1;
}
}
}
return dp.back().back();
}
};