leetcode 72. Edit Distance DP动态规划 + 编辑距离

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的过程。

用dp[i][j]表示从word1[i]变为word2[j]所需要的最少步骤。那么主要分为一下几种情况处理:
1) 替换代价:若word1[i]=word2[j] , 则只需把word1[0…i-1]变为word2[0…j-1],equalCost = dp[i-1][j-1],否者equalCost = dp[i-1][j-1]+1;

2) 插入代价:若在word1[i]插入某字符是word1到word2[的最小改动,insertCost= dp[i][j-1] + 1;

3) 删除代价:若删除word1[i]是word1到word2的最小改动,则deleteCost = dp[i-1][j] + 1。

最后dp[i][j]是替换代价、插入代价和删除代价的最小值。

代码如下:

public class Solution 
{
    /*
     * http://www.bubuko.com/infodetail-644271.html
     * 
     * 这个题吧比较难,动态规划DP解决                                                   
     * */

    public int minDistance(String word1, String word2) 
    {
        if(word1==null || word1.length()<=0)
            return word2.length();
        if(word2==null || word2.length()<=0)
            return word1.length();

        int [][]dp=new int[word1.length()+1][word2.length()+1];
        for(int i=0;ilength;i++)
            dp[i][0]=i;
        for(int i=0;i0].length;i++)
            dp[0][i]=i;

/*      用dp[i][j]表示从word1[i]变为word2[j]所需要的最少步骤。

        1) 匹配:若word1[i]=word2[j] , 则只需把word1[0...i-1]变为word2[0...j-1]
                即可. ==> dp[i][j] = dp[i-1][j-1].

        2) 替换:把word1[i]替换word2[j]是从word1到word2的最小改动,
        则 先把word1[0...i-1]以最小代价变为word2[0...j-1],再替换. ==> dp[i][j] = dp[i-1][j-1] + 1.

        3) 插入:若在word1[i]插入某字符是word1到word2[的最小改动,
                                          则先把word1[0...i]以最小代价变为word2[0...j-1],在此基础上加上word2[j], ==> dp[i][j] = dp[i][j-1] + 1.

        4) 删除:若删除word1[i]是word1到word2的最小改动,
        则先把word1[0...i-1]以最小代价变为word2[0...j], 再删除word1[j]即可,
        dp[i][j] = dp[i-1][j] + 1.*/

          for(int i=1;i<=word1.length();i++)
          {
              for(int j=1;j<=word2.length();j++)
              {
                  int addA=dp[i][j-1]+1;
                  int deleteA=dp[i-1][j]+1;
                  int eqA=0;
                  if(word1.charAt(i-1)==word2.charAt(j-1))
                      eqA=dp[i-1][j-1];
                  else
                      eqA=dp[i-1][j-1]+1;
                  dp[i][j]=Math.min(addA, Math.min(deleteA, eqA)); 
              }
          }
        return dp[word1.length()][word2.length()];
    }
}

下面是C++的做法,就是一个很经典但是也很难想的DP动态规划的做法

代码如下:

#include 
#include 
#include 
#include 

using namespace std;

class Solution
{
public:
    int minDistance(string word1, string word2) 
    {
        int m = word1.length(), n = word2.length();
        vector<vector<int> > dp(m + 1, vector<int>(n + 1, 0));
        for (int i = 1; i <= m; i++)
            dp[i][0] = i;
        for (int j = 1; j <= n; j++)
            dp[0][j] = j;
        for (int i = 1; i <= m; i++) 
        {
            for (int j = 1; j <= n; j++) 
            {
                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] + 1, min(dp[i][j - 1] + 1, dp[i - 1][j] + 1));
            }
        }
        return dp[m][n];
    }
};

你可能感兴趣的:(leetcode,For,Java,需要好好想一下的题目,DP动态规划,leetcode,For,C++)