Edit Distance - LeetCode

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。

设置DP[i][j]表示word1[0...i-1]与word2[0...j-1]匹配所需要的最小操作数。

先考虑边界情况,即空串与另一个字符串进行匹配。比如""与word1[0...i-1]匹配,很明显操作数为i,即做i次删除操作,因此dp[i][0] = i。同理,dp[0][j] = j。

现在考虑普遍情况,即i > 0且j > 0时:

假如我们已经知道了word1[0...i-2]与word2[0...j-2]匹配所需要的最小操作数,即dp[i-1][j-1]。如果word1[i-1]等于word2[j-1],则我们不需要任何额外操作,这种情况下dp[i][j] = dp[i-1][j-1]。

假如word1[i-1]与word2[j-1]不同,则我们有三种可进行的操作:

  1. 将word1[i-1]与word2[j-1]其中的一个替换成另一个。这种情况下dp[i][j] = dp[i-1][j-1] + 1。
  2. 将word1[i-1]删掉,使word1[0...i-2]与word2[0...j-1]匹配上,则dp[i][j] = dp[i-1][j] + 1;或者将word2[j-1]删掉,使word1[0...i-1]与word2[0...j-2]匹配上,则dp[i][j] = dp[i][j-1] + 1。
  3. 在word1[i-1]后面插入一个word2[j-1],使word1[0...i-1]与word2[0...j-2]匹配,即dp[i][j] = dp[i][j-1] + 1;或者在word2[j-1]后面插入一个word1[i-1],则dp[i][j] = dp[i-1][j] + 1。

这里可以发现,情况2和3里的递推公式其实是一样的。

因此,当word1[i-1]与word2[j-1]不同时,我们有递推公式:

dp[i][j] = min(dp[i-1][j-1], dp[i-1][j], dp[i][j-1]) + 1。

此外,dp[i][j]的值只与公式中的3个值有关,更具体一点说,dp[i][]的值只与dp[i][]以及dp[i-1][]这两行中的3个值有关。因此,在递推过程中,我们不需要保持一个m * n的数组,只要有2 * m或者2 * n就够了。空间复杂度为O(m + n)。

 1 class Solution {
 2 public:
 3     int minDistance(string word1, string word2) {
 4         int len1 = word1.size(), len2 = word2.size();
 5         if (len1 * len2 == 0)
 6             return len1 + len2;
 7         vector<int> tem(len2 + 1, 0);
 8         vector<vector<int> > dp(2, tem);
 9         for (int i = 1; i <= len2; i++)
10             dp[0][i] = i;
11         for (int i = 1; i <= len1; i++)
12             for (int j = 0; j <= len2; j++)
13             {
14                 if (j == 0) dp[i % 2][j] = i;
15                 else if (word1[i - 1] == word2[j - 1])
16                     dp[i % 2][j] = dp[(i - 1) % 2][j - 1];
17                 else
18                     dp[i % 2][j] = min(dp[(i - 1) % 2][j - 1],
19                         min(dp[(i - 1) % 2][j], dp[i % 2][j - 1])) + 1;
20             }
21         return dp[len1 % 2][len2];
22     }
23 };

 

posted @ 2015-11-08 12:56  fenshen371  阅读(142)  评论(0编辑  收藏  举报