编辑距离

编辑距离

原题是LeetCode 72.编辑距离

给你两个单词 word1 和 word2,请你计算出将 word1 转换成 word2 所使用的最少操作数 。

你可以对一个单词进行如下三种操作:

插入一个字符
删除一个字符
替换一个字符
 

示例 1:

输入:word1 = "horse", word2 = "ros"
输出:3
解释:
horse -> rorse (将 'h' 替换为 'r')
rorse -> rose (删除 'r')
rose -> ros (删除 'e')
示例 2:

输入:word1 = "intention", word2 = "execution"
输出:5
解释:
intention -> inention (删除 't')
inention -> enention (将 'i' 替换为 'e')
enention -> exention (将 'n' 替换为 'x')
exention -> exection (将 'n' 替换为 'c')
exection -> execution (插入 'u')

这题刚开始看毫无头绪,找不到“最优”的方法,因此打开了题解,发现这是一个从来没见过的题型,并且貌似是一个广泛应用的算法,因此将其记录下来。

编辑距离算法被数据科学家广泛应用,是用作机器翻译和语音识别评价标准的基本算法。

这个算法本质还是DP。分析思路如下:

假设有词A和词B,想要把A转换成B(与把B转换成A等价),且只能运用增、删、换三种方法操作单个词,因此总共可以归纳为三种操作方法:

  • 在A中增加一个字母(与在B中删掉一个字母等价)
  • 在A中删掉一个字母(与在B中增加一个字母等价)
  • 在A中替换一个字母(与在B中替换一个字母等价)

现在视线回到A和B:

  • A的最后一个字母(A[i])与B的最后一个字母(B[j])是相等的,那么将A转换为B就和把A[0…i-1]转换为B[0…j-1]是等价的。
  • 若不相等,我们可以对A进行上述三种操作:
  • ① 在A的末尾增加一个字母,使之等于B[j],这样的话,将现在的A转换为B就和把A[0…i]转换为B[0…j-1]是等价的。
  • ② 在B的末尾增加一个字母,使之等于A[i],这样的话,将现在的A转换为B就和把A[0…i-1]转换为B[0…j]是等价的。
  • ③ 将A[i]替换为B[j],这样的话,将现在的A转换为B就和把A[0…i-1]转换为B[0…j-1]是等价的。
    因为上述三种情况都是和操作后的A、B等价,因此都要操作数都要+1
    模式匹配:对于当前的问题,我们可以通过求解它的子问题来获得答案。这种情况下,一般使用自顶而下的递归或者自底向上的动态规划。众所周知递归耗费空间以及修枝很麻烦,因此一般还是DP。

上代码:

class Solution {
public:
    int minDistance(string word1, string word2) {
        int len1 = word1.size(), len2 = word2.size();
        vector<vector<int>> dp(len1+1, vector<int>(len2+1));
		//初始化
        for (int i = 0; i <= len2; i++)
        {
            dp[0][i] = i;
        }
        for (int i = 0; i <= len1; i++)
        {
            dp[i][0] = i;
        }
		//自底向上DP
        for (int i = 1; i <= len1; i++)
        {
            for (int j = 1; j <= len2; 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],min(dp[i][j-1],dp[i-1][j-1])) + 1;
                }
            }
        }
        return dp[len1][len2];
    }
};

问题解决,这个算法要记住!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值