[路飞]_72. 编辑距离

141 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第3天,点击查看活动详情

今天我们来做一下leetcode上面的一道比较经典字符串类动态规划题目 72. 编辑距离

题意

image.png

题意比较简单,给我们两个字符串word1和word2,让我们求从word1转换成word2的最小次数,转换的操作可以有三种

  • 向word1中插入一个字符
  • 将word1中一个字符删除
  • 替换word1中的一个字符为另外一个

像我一样初次接触动态规划的同学,我推荐一个理解动规类题目思路的方法,可能不是很实用,但是很有效。

那就是我们拿一支笔、一张纸手动画出递推的表格,手动模拟一次完整的递推过程,当我们弄明白大概的递推过程之后,对于我们理解边界情况和后续的代码编写都会有很大的好处。

相信做过一些动态规划类题目的同学,尤其是字符串类动态规划,会发现其中的一些套路,这道题也不例外。

别看题目的标签打的是困难,但是实际难度比另外一道同样的字符串DP的题目剑指 Offer 19. 正则表达式匹配难度小很多

思路

既然是要使用动规进行解答,那么就少不了分析其中的递推过程,也就是我们可以从最简单的情况开始考虑,根据递推 关系解出更大规模的问题。 例如 word1=horse word2 = ros 记:m = word1.length,n = words2.length

  • 状态定义 dp[i][j]表示word1前i个字符变成word2前j个字符的最小操作数

  • 状态初始化

    • 假设word1为空,那么word1变成word2的操作只能是新增,具体的操作数应该等同于word2中的字符数
      • 具体代码如下 dp[0][j] = j j的范围是[0-n]
    • 同样,假设word2为空,那么word1变成word2的操作只能删除,具体的操作数应该等于word1的字符数
      • 具体代码如下 dp[i][0] = i i的范围是[0-m]
  • 状态转移方程

    • 考虑word1的前i位如何变成word2的前i位时,需要看最后一位是否相同,即word1[i-1] word2[j-1]
      • 如果word1[i-1]==word2[j-1] 那么dp[i][j] = dp[i-1][j-1]
      • 如果不同的话,考虑不同的编辑方式
        • 如果替换,dp[i][j] = dp[i-1][j-1] + 1
        • 如果删除,即删除word1的最后一个字符,那么有 dp[i][j] = dp[i-1][j] + 1
        • 如果新增,即新增word2的最后一个字符,那么有 dp[i][j] = dp[i][j-1] + 1
        • 最终的结果取三者的最小值

至此,我们就分析完了这道题目

代码实现

image.png

结束语

如果有更好的分析思路,欢迎大家在评论区发表看法!⛄