算法整理——【动态规划练习(9)编辑距离】

编辑距离是一道较为复杂的题,但在通过前面的动态规划练习后使用动态规划解决该问题会简单一些。

一、题目介绍和分析

题目为72. 编辑距离 - 力扣(LeetCode),给你两个单词 word1 和 word2, 请返回将 word1 转换成 word2 所使用的最少操作数  。你可以对一个单词进行如下三种操作:插入一个字符、删除一个字符、替换一个字符。

虽然题目说的是对word1的最少操作数,但如果对word2也进行操作也是同样的计数,后续分析中会涉及到这个小思路。现在我们使用动规五部曲分析。

①dp数组及其下标含义。dp[i][j]为word1中[0,i]到word2[0,j]的最小操作次数。

②递推公式。我们需要比较元素是否相同,如果word1[i]和word2[j]相同,则不需要操作,dp[i][j]=dp[i-1][j-1]。如果不相同,就需要操作了。操作分为删除、插入和替换。如果是删除,则要么把word1[i]删去,然后值就应该为dp[i-1][j]+1,要么删word2[j],然后值为dp[i][j-1]+1(此处,对两个都考虑了删除,则实际上等于考虑过了添加操作,因为删除和添加操作是对应的);如果是替换,就是把word1[i]和word2[j]成为相同的,此时值为dp[i-1][j-1]+1。我们需要在这三个式子中取最小。

③初始化。主要对dp数组的第一行和第一列进行初始化。第一行为word1[0]变换到word2[0,i]的操作数,如果word1[0]==word2[i]则只需要把其余i位删除即可,如果不等则值是在dp[0][i-1]的基础上+1。第一列为word2[0]变换到word1[0,i]的操作数,如果word2[0]==word1[i],则只需要把其余i位删除即可,如果不等则值是在dp[i-1][0]的基础上+1。这里可以举个例子方便理解,例如word1=add,word2=d,第一行为[1,1]第一列为[1,1,2]。

④遍历顺序。由递推公式得,我们需要从左往右从上往下遍历。

⑤打印并检查dp数组。

二、完整代码

class Solution {
public:
    int minDistance(string word1, string word2) {
        if(word1.size()==0||word2.size()==0)return max(word1.size(),word2.size());
        vector<vector<int>> dp(word1.size(),vector<int>(word2.size(),0));
        //初始化
        if(word1[0] == word2[0]) dp[0][0] = 0;
        else dp[0][0] = 1;
        for(int i = 1; i<word2.size(); i++)
        {
            if(word1[0]!=word2[i])dp[0][i] = dp[0][i-1]+1;
            else dp[0][i] = i;
        }
        for(int i = 1; i<word1.size(); i++)
        {
            if(word2[0]!=word1[i]) dp[i][0] = dp[i-1][0]+1;
            else dp[i][0] = i;
        }
        //遍历
        for(int i = 1; i<word1.size(); i++)
        {
            for(int j = 1; j<word2.size(); j++)
            {
                if(word1[i]!=word2[j])
                {
                    dp[i][j] = min(dp[i-1][j]+1,min(dp[i][j-1]+1,dp[i-1][j-1]+1));
                }
                else
                {
                    dp[i][j] = dp[i-1][j-1];
                }
            }
        }
        return dp[word1.size()-1][word2.size()-1];
    }
};

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值