彻底理解动态规划:编辑距离

大家好,我是小风哥。,这是动态规划主题的第三篇,本篇的题目非常经典,几乎是面试必备,即,编辑距离问题,edit distance;,给定两个字符串word1以及word2,返回将word1转为word2需要的最少步骤,在每一步中你可以针对字符串word1进行以下操作:,假如word1是”horse”,word2是“ros”,那么你的程序需要返回3,也就是说将word1转为word2至少需要三个步骤:,想一想该怎样用动态规划解决这个问题。,和之前的题目一样,你首先应该找出子问题是什么,子问题与原始问题的依赖关系是什么。,找出子问题的关键在于每一步的选择。,如果word1与word2的第一个字符相等,假设word1是hor、word2是hr,那么我们可以放心的排除掉两个字符串的第一个字符,即EditDistance(“hor”, “hr”)一定等于EditDistance(“or”, “r”):,图片,此时我们得到了一个子问题EditDistance(“or”, “r”),原始问题EditDistance(“hor”, “hr”)的值等于该子问题。,真正有趣的是如果word1与word2的第一个字符不相等的情况,假设word1为“hor”,而word2为“ro”,此时根据该问题的规则针对word1的第一个字符有三种操作:,1,在word1的第一个字符前新增(Insert)一个字符r,此时word1变为rhor,由于此时word1 的第一个字符等于word2的第一个字符,可以放心的忽略掉,因此我们得到了子问题EditDistance(“hor”,”o”),由于执行了一次新增操作,因此:,2,将word1的第一个字符删掉(Delete),此时word1变为“or”,我们得到了一个新的子问题EditDistance(“or”,”ro”),由于执行了一次删除操作,因此:,3,将word1的第一个字符替换(Replace )为r,此时word1变为了“ror”,由于word1的第一个字符等于word2的第一个字符,因此可以放心的忽略掉,我们得到了一个新的子问题EditDistance(“or”,”o”),由于执行了一次删除操作,因此:,根据题目要求,我们需要得到最小的编辑距离,因此:,即:,图片,可以看到,如果word1与word2的第一个字符如果不相等的话那么我们会得到三个子问题,取这三个子问题的最小值然后加1就是原始问题的解。,现在我们找到了子问题与原始问题之间的依赖关系。,实际上,根据上述讨论我们还可以进一步扩展从而得到完整的状态空间树。,图片,从这棵树中可以看到最小的编辑距离是2。,现在你应该清楚的知道该怎样我们是怎样一步步将问题不断的分解为更小的子问题,然后利用子问题的解来得到原始问题的解了。,上图中每个方框都是一个子问题,决定一个子问题的因素在于word1与word2当前处理到了哪个位置,假设对word1处理到了第i个位置,对word2处理到了第j个位置,因此我们可以对问题进行定义:,该函数表示从i到word1的末尾形成的字符串与从j从word2的末尾形成的字符串的编辑距离。,因此如果调用该函数时我们应该这样使用:,有了该定义与上述分析,你可以轻而易举的写出这样的递归代码:,我们将word1与word2声明为全局变量,这样你可以清楚的看到决定EditDistance函数值的因素只有这两个参数i和j,i的取值为[0, word1.length()],j的取值为[0, word2.length()],也就是说子问题的个数只有(word1.length() + 1) * (word2.length() + 1) 个,上述递归代码存在大量重复计算问题,因此可以通过增加cache进行优化,这个改动就留给大家啦。,接下来我们着手将自顶向下的递归代码改为自底向上的动态规划代码。,
,由于子问题的个数只有(word1.length() + 1) * (word2.length() + 1) 个,因此可以定义一个相同大小的二维数组dp:,接下来我们要求解最小子问题,最小子问题就是上述递归代码的递归出口:,该最小子问题的解包含在了dp数组的初始化中。,接下来的子问题是另外两个递归出口:,我们可以简单的构造出两种情况下的所有i和j来初始化数组dp,即:,最后我们利用两个for循环来构造出所有的i和j,从而将递归函数的最后一部分:,放置在for循环中,并将对递归函数的调用替换为对数组dp的读写:,最终,完整的动态规划代码为:,

文章版权声明

 1 原创文章作者:cmcc,如若转载,请注明出处: https://www.52hwl.com/17307.html

 2 温馨提示:软件侵权请联系469472785#qq.com(三天内删除相关链接)资源失效请留言反馈

 3 下载提示:如遇蓝奏云无法访问,请修改lanzous(把s修改成x)

 免责声明:本站为个人博客,所有软件信息均来自网络 修改版软件,加群广告提示为修改者自留,非本站信息,注意鉴别

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023年3月5日 上午12:00
下一篇 2023年3月7日 下午10:34