您的位置:首页 > 其它

LeetCode刷题 | 72. Edit Distance 难题 编辑距离dp

2017-12-26 15:55 531 查看
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

所谓的求字符串的编辑距离就是给你两个字符串A和B,每次对A进行下列三个操作之一:

1)       改变一个字符

2)       删除一个字符

3)       增加一个字符

将A变成B所需要的最小步骤数就是AB之间的编辑距离。

1如何使用笔算出AB之间的编辑距离

首先分析AB的长度,对其中较短的字符串进行加0填充,使填充之后的字符串长度相等,并且保证填充后的字符串之间每一位尽可能的相等,比如A是aabbcc,B为aawbbwccw,那么A填充之后变成A^:aa0bb0cc0,需要注意的是,0并不是一个字符,只是表示一个占位,

这时可以得到A和B 的编辑距离,将A^和B一一对应,不相等的位数的个数就是A到B所需要的最短编辑距离,同时也是B变成A的最短编辑距离,这里为3

2AB之间的编辑距离计算编程思路

1)       AB最后一位相等

设A长度为i位,B长度为j位,d(i,j)为A,B之间的编辑距离,当A[i]==B[j]的时候,对其中较短的一个字符串进行加0填充,这里假设是A,填充后为A^,那么在填充之后B[j]所对应的字符有两种情况,其一是B[j]对应A[i],那么这里很明显,d(i,j)==d(i-1,j-1)成立,当B[j]对应0的时候,这是可以在不改变编辑距离的情况下对A^进行更改,将A^的最后一个0与前一个与B[j]相等的字符交换位置,这个时候A^和B之间的不同位数不会改变,编辑距离也就不会改变,这个时候d(i,j)==d(i-1,j-1)成立

2)       AB最后一位不等

当AB最后一位不等的时候,A^和B最后一位有两种情况,0和一个字符,这个假设A^最后为0,那么最后一步为插入字符,那么d(i,j)=d(i,j-1)+1,当A^和B最后一位为两个不同字符的时候,那么最后一步为更改字符,d(i,j)=d(i-1,j-1)+1,

3)       递推公式

综上所述,能很容易的得到AB之间编辑距离的递推公式,

d(i,j)=min{d(i-1,j-1)+@(A[i],B[j]),d(i-1,j)+1,d(i,j-1)+1}

@(A[i],B[j])的值当A[i]==B[j]时为0,当A[i]!=B[j]时为1

接下来是递归的算法,但是这样的递归写法可能会导致超时,我的这个算法就超时了,所以接下来使用循环的非递归算法来解决这个问题

通过这个问题的学习我学会了vector二维数组的写法,类似于这样:vector<vector<int>> dp
4000
(word1.length()+1, vector<int>(word2.length()+1,-1));

 

class Solution {

public:

    int f(int i, int j,vector<vector<int>> dp,string word1,string word2)

{

      if (dp[i][j] != -1)

            return dp[i][j];

      if (word1[i-1] == word2[j-1])

            return dp[i][j]=f(i - 1, j - 1, dp,word1, word2);

     else return dp[i][j] = 1+min(f(i - 1, j -1, dp, word1, word2),min(f(i, j - 1, dp, word1, word2), f(i - 1, j, dp, word1,word2)));

}

intminDistance(string word1, string word2) {

      vector<vector<int>>dp(word1.length()+1, vector<int>(word2.length()+1,-1));

      for (int i = 0; i <= word1.length();i++) dp[i][0] = i;

      for (int i = 0; i <= word2.length();i++) dp[0][i] = i;

      return f(word1.length(), word2.length(),dp,word1,word2);

}

};

 

非递归算法:

class Solution {

public:

    int minDistance(string word1, string word2){

      vector<vector<int>>dp(word1.length()+1, vector<int>(word2.length()+1,-1));

      for (int i = 0; i <= word1.length();i++) dp[i][0] = i;

      for (int i = 0; i <= word2.length();i++) dp[0][i] = i;

      for (int i = 1; i <= word1.length();i++)

            for (int j = 1; j <=word2.length(); j++)

                  if (word1[i-1] == word2[j-1])dp[i][j] = dp[i - 1][j - 1];

                  else

                  {

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

                  }

     

      return dp[word1.length()][word2.length()];

}

};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: