题目描述
Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2. (each operation is counted as 1 step.)
You have the following 3 operations permitted on a word:
a) Insert a character
b) Delete a character
c) Replace a character
算法分析
这是一道很经典的动态规划问题。使用dp[i][j]
来表示word1
的前i
个字符转变为word2
的前j
个字符的编辑距离。为了方便,以下假设word1/word2
的下标由1开始,即word1[1:3]
表示字符串{word1[0], word[1], word[2]}
。那么,dp[i][j]
表示word1[1:i]
和word2[1:j]
的编辑距离。
假设现在已知dp[i-1][j-1]
,即已经知道word1[1:i-1]
到word2[1:j-1]
的编辑距离,那么对于word1[i]
和word2[j]
,有两种情况:
1. `word1[i] == wprd2[j]`。此时,显然有`dp[i][j] = dp[i-1][j-1]`
2. `word1[i] != word2[j]`。这时,就有可能发生三种操作:insert, delete和replace。
考虑word1[i] != word2[j]
时,若:
word1[1:i]
通过insert可以得到word2[1:j]
,即word1[1:i] == word2[1:j-1]
,那么有:dp[i][j] = dp[i][j-1]+1
。word1[1:i]
通过delete可以得到word2[1:j]
,即word1[1:i-1] == word2[1:j]
,那么有:dp[i][j] = dp[i-1][j]+1
。word1[1:i]
直接通过replace可以得到word2[1:j]
,即word1[1:i-1] == word2[1:j-1]
,那么有:dp[i][j] = dp[i-1][j-1]+1
。
综上,可以得到状态转移方程:1
2
3
4if (word1[i - 1] == word2[j - 1])
dp[i][j] = dp[i-1][j-1];
else
dp[i][j] = min(dp[i - 1][j - 1], dp[i - 1][j], dp[i][j - 1]) + 1;
另外,再考虑边界条件,即:1
2dp[i][0] = i;
dp[0][j] = j;
代码实现
代码实现:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18class Solution {
public:
int minDistance(string word1, string word2) {
int m = word1.length(), n = word2.length();
vector<vector<int>> dp = vector<vector<int>>(m + 1, vector<int>(n + 1, 0));
for (int i = 0; i <= m; i++) {
for (int j = 0; j <= n; j++) {
if (i == 0) { dp[i][j] = j; continue; }
if (j == 0) { dp[i][j] = i; continue; }
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 - 1][j], dp[i][j - 1])) + 1;
}
}
return dp[m][n];
}
};
本文为博主原创文章,转载请注明出处。