【动态规划】edit distance 一个字符串->另一个字符串的编辑距离

【动态规划】edit distance 一个字符串->另一个字符串的编辑距离_第1张图片

一个字符串到另一个字符串,3种操作(增加、删除、替换),问要做多少步。

大致思路:

这道题的动态规划让我理解了一个小时。。。。。

来看方法:

【动态规划】edit distance 一个字符串->另一个字符串的编辑距离_第2张图片

理解的基础是要get一个点:f[i][j]表示word1[0..i]已经成功转换成word2[0...j]了的步数!

所以,在聚焦于看一个字符时,来想想是怎么达到f[i][j]这个目的的,从而推出状态转移。就三种方法嘛:替换 删除 添加。那么你就要结合f[][]想:怎样通过替换、删除、添加能使word1[0..i]成功转换成word2[0...j]呢?

(1)如果word1[i]==word2[j],那么显然f[i][j]=f[i-1][j-1];

(2)如果word1[i]!=word2[j],那么:

  • 若能够通过替换来使word1[0..i]成功转换成word2[0...j]的,那么要满足在这之前的都转换好,再把这个word1[i]替换成word2[j]吧,所以f[i][j]=f[i-1][j-1]+1。
  • 若能够通过删除来使word1[0..i]成功转换成word2[0...j]的,那么要满足删除字符==word1[i]之后对应上吧,所以f[i][j]=f[i-1]f[j]+1.
  • 若能够通过添加来使word1[0..i]成功转换成word2[0...j]的,那么要满足添加字符==word2[j]之前能对应上吧,所以f[i][j]=f[i]f[j-1]+1.

反正。。。这个理解啊。。不是说“上一步我干了什么”,而是主要是抓住“我这一步要干啥能够达到dp数组的定义”,然后再来联系写出转移方程。(不知道这个理解会不会对未来想dp有帮助)

AC代码:

class Solution {
public:
    int minDistance(string s1, string s2) {
        int dp[1000][1000];
        int len1 = s1.size();
        int len2 = s2.size();
        if(len1==len2&&len1==0)
            return 0;
        if(len1==0)
            return len2; //就一直删到为空
        if(len2==0)
            return len1;
        
        for(int i=0;i<1000;i++)
        {
            dp[i][0]=i;
            dp[0][i]=i;
        }
        for(int i=1;i<=len1;i++)
        {
            for(int j=1;j<=len2;j++)
            {
                if(s1[i-1]==s2[j-1])  //差点又忘了,由于存在i-1和j-1的关系i,j故意从1开始,所以取字符串要少1才行
                    dp[i][j]=dp[i-1][j-1];
                else
                {
                    dp[i][j] = min(min(dp[i-1][j-1],dp[i-1][j]),dp[i][j-1])+1;
                }
            }
        }
        return dp[len1][len2];
    }
};


 

你可能感兴趣的:(LeetCode,保研机试)