LeetCode 72. Edit Distance

题目描述

72. Edit Distance

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]时,若:

  1. word1[1:i]通过insert可以得到word2[1:j],即word1[1:i] == word2[1:j-1],那么有:dp[i][j] = dp[i][j-1]+1
  2. word1[1:i]通过delete可以得到word2[1:j],即word1[1:i-1] == word2[1:j],那么有:dp[i][j] = dp[i-1][j]+1
  3. 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
4
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], dp[i - 1][j], dp[i][j - 1]) + 1;

另外,再考虑边界条件,即:

1
2
dp[i][0] = i;
dp[0][j] = j;

代码实现

代码实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class 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];
}
};

本文为博主原创文章,转载请注明出处。