编程之美3.3
看完题后,毫无头绪
书上的解题思路很好,首先两个字符串的距离肯定是个可知数,必须小于两字符串之和。
可以通过删除操作将两个串都变成空串。
书上所示的递归方法,代码敲出来了,有点点不同
因为上述的代码存在重复子问题,可以优化,利用将子问题计算后的结构暂存,再次调用时可以直接查结果。
涉及到重复子问题,联想到动态规划的备忘录...具体实现,嗯,需要参考资料了...
参考文章:
http://tech.ddvip.com/2009-05/1243159182120785_3.html
先转DP解法代码
动态规划算法总是充分利用重叠子问题,即通过每个子问题只解一次,把解保存在一个需要时就可以查看的表中,而每次查表的时间为常数。
动态规划算法是有底向上的。
再转备忘录做法:
备忘录是动态规划的一种变形,它既具有通常的动态规划方法的效率,又采用了一种自顶向下的策略。
加了备忘的递归算法为每一个子问题的解在表中记录一个表项。开始时,每个表项最初都包含一个特殊的值,以表示该表项有待填入。当在递归算法的执行中第一次遇到一个子问题时,就计算它的解并填入表中。以后每次遇到该子问题时,只要查看并返回先前填入的值即可。
下面是原文递归算法的做备忘录版本,并通过布尔变量memoize来控制是否使用备忘录,以及布尔变量debug来控制是否打印调用过程。有兴趣的读都可以通过这两个布尔变量的控制来对比一下备忘录版本与非备忘录版本的复杂度。
总结 :
可以计算出,如果不用动态规划或是做备忘录,最坏情况下复杂度约为:lenA!*lenB!。使用动态规划的复杂度为O((lenA+1)*(lenB+1))。递归并做备忘录的方法最坏情况下复杂度为O((lenA+1)*(lenB+1))。
在实际应用中,如果所有的子问题都至少要被计算一次,则一个自底向上的动态规划算法通常要比一个自顶向下的做备忘录算法好出一个常数因子,因为前者无需递归的代价,而且维护表格的开销也小些。
此外,在有些问题中,还可以用动态规划算法中的表存取模式来进一步减少时间或空间上的需求。或者,如果子问题空间中的某些子问题根本没有必要求解,做备忘录方法有着只解那些肯定要求解的子问题的优点,对于本问题就是这样。

2034

被折叠的 条评论
为什么被折叠?



