leetcode学习日记5-编辑距离

南楼画角 提交于 2019-11-26 20:44:55

leetcode学习日记5-编辑距离

给定两个单词word1和word2,计算出将word1转换成word2所使用的最少操作数。你可以对一个单词进行三种操作
插入一个字符
删除一个字符
替换一个字符

实例:
输入
word1=“horse”,word2=“rose”
输出
3
解释:
horse->rorse
rorse->rose
rose->ros

思路:
动态规划

  1. 一个单词word1通过三种途径靠近下一个单词word2
  • 考虑如果word1从0 ~ i-1位要和word2的0 ~ j-1位相同需要k步,则word1从0 ~ i位与word2的0 ~ j位相同需要几步?
    分两种情况:

    1. 若word1的i位与word2的j位相同,那直接就搞定了,总共k步
    2. 若word1的i位与word2的j位不同,那就替换第i位,k+1
  • 考虑如果word1从0 ~ i位要和word2的0 ~ j-1位相同需要k步,则word1从0 ~ i位与word20 ~ j位相同需要几步?

    k+1步,加上缺少的字符。

  • 考虑如果word1从0 ~ i-1位要和word2的0 ~ j位相同需要k步,则word1从0i-1位与word20j位相同需要几步?

    k+1步,加上多余的字符。

通过以上总结可以得出动态规划的状态转移公式。

还缺少初始值和循环方式。由于缺少的是最小值,初始值都填最大值。
一开始以为如果word1有i位,word2有j位,变换的最长路径是先把word1完全删除再加上word2,总共需要i+j步。
后来发现,因为可以替换字符,故min(i, j)次替换,再abs(i-j)次删减或增加也是可以的,故最长其实是max(i, j)。

class Solution {
public:
    int minDistance(string word1, string word2) {
        int s1=word1.size();
        int s2=word2.size();
        int i,j;
        int dp[s1+1][s2+1];
         for(i=0;i<=s1;i++)
        {
            for(j=0;j<=s2;j++)
            {
                dp[i][j]=max(i,j);
            }
        }
        for(i=1;i<=s1;i++)
        {
            for(j=1;j<=s2;j++)
            {
                if(word1[i-1]==word2[j-1])
                {   //cout<<word1[i-1]<<' '<<word2[j-1]<<endl;
                    dp[i][j]=min(dp[i][j],dp[i-1][j-1]);
                   
                }
                
                else
                dp[i][j]=min(dp[i][j], dp[i-1][j-1]+1);
                //cout<<dp[i][j]<<endl;
                dp[i][j]=min(dp[i][j], dp[i-1][j]+1);
                //cout<<dp[i][j]<<endl;
                dp[i][j]=min(dp[i][j], dp[i][j-1]+1);
                //cout<<dp[i][j]<<endl;
            }
        }
        
        return dp[s1][s2];
        
        
    }
};
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!