【LeetCode每日一题系列】编辑距离

前言
编辑距离,经典的动态规划问题,在leetcode72题,属于困难题目。编辑距离主要的困难在于思考如何去进行状态的转移与选择。接下来,我们将一步一步分析,解决编辑距离的相关问题。


题目描述

给你两个单词 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’)

提示:

0 <= word1.length, word2.length <= 500
word1 和 word2 由小写英文字母组成

思路分析

编辑距离问题就是给定了两个字符串word1,word2,只能使用三种操作即删除、插入、替换,将word1变成word2,求最少的操作数。其中,word1和word2两者之间的变换,无论是word1变换为Word2还是word2变换成word1,最短的编辑距离应该都是一样的。 因此,我们只需要考虑其中一种变换就可
解决双字符串动态规划问题,一般使用双指针i,j分别指向两个字符串的串尾,随后不断往前往前缩减,缩小问题的规模
接下来,我们简单看一下示例1中word1怎么转换为word2的

word1 = "horse", word2 = "ros"
word1: h o r s e
word2: r o s
================
1:
               i
word1: h o r s e
word2: r o s
           j
word1[i] != word2[j] 删除word1[j] i--  (第一次操作)
================
2:
             i
word1: h o r s
word2: r o s
           j
word1[i] == word2[j] 跳过,i--,j--
=================
3:
           i
word1: h o r s
word2: r o s
         j  
word1[i] != word2[j] 删除word1[i],i-- (第二次操作)
==================
4:
         i
word1: h o s
word2: r o s
         j
word1[i] == word2[j] 跳过,i--,j--
==================
5:
       i
word1: h o s
word2: r o s
       j
word1[i] != word2[j] 替换word1[i],i--,j--   (第三次操作)
===================
6:
       i
word1: r o s
word2: r o s
       j
word1[i] != word2[j] 跳过,i--,j--
===================
i < 0 , j < 0 结束

根据上述步骤,我们发现其实字符串转换过程中,不止包含三个操作,其实还有第4个操作【跳过】,即什么都不做。因为本身两个字符已经相同了,而我们为了使编辑距离尽可能的小,因此应该尽可能的补缺改动本来相同的字符。
另外除了上述可能的情况外,我们还需要考虑一个问题:i或者j提前走完了。也就是说,其中一方多了部分字符串,此时只能采用删除或者插入方法不断的缩减两个字符串之间的差距。看下方示例:

		 i
word1:   a r o s
word2:   r o s
	   j

上述两种i,j 提前走后属于是算法的base case

初步代码

动态规划 递归等常用方法,都需要考虑base case情况。在上述介绍中,我们了解到base case就是 i 走完word1,或者j走完s2,可以直接返回另一个字符出剩下的长度。
同时,对于每对字符是word1[i] 和 word2[j] ,存在4中操作方式:

if (word1[i] == word2[j]){
   
	skip;
	i++;j++;
}else{
   
	三选一:
	insert,
	delete,
	replace
}

针对这个代码框架,我们再来确定一下动态规划所必须的要素:状态以及选择。 状态即i,j位置,选择则是4种操作skip,insert,delete,replace。
这里先提供算法代码,后面会对代码进行详细解释:

//dp函数的定义
//s1[0..i] 和 s1[0..j]的最小编辑距离是dp(i,j)
int dp(string s1,string s2,int i,
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值