分治、动态规划、贪心算法的对比
文章分治法,动态规划及贪心算法区别中比较三种算法思路,简而言之,很多问题都可以用分治思路求解,将复杂问题转化为多个稍微简单的子问题,问题分解为子问题,犹如树形结构一般,但树的分叉(问题的分级扩展)有二叉树、B树,分叉等级不同;但一些问题的子问题,相互独立,且有重叠,导致树的分叉(问题的分级扩展)很少,子问题的数目约等于子子问题的数目。至于贪心算法,问题直接转化为最优子问题。贪心算法总对应一个更复杂的动态规划算法。但是如何确定问题能够使用贪心算法,算法导论中,并未给出一般性的证明,而是说明,问题必须具有最优子结构——问题的最优解包含子问题的最优解,同时需要证明,最优子解+贪心选择,就是最优解,通常反证法能够证明这样的问题。
那么对于算法如何选择,也就有了一般思路:能够分解的问题,就能够使用分治,通常经过分解的子问题独立,分治的算法实现通常是递归;子问题重叠,导致每一层级的问题扩展性低的问题,就能用动态规划;而具有最优子结构,同时能够证明最优子解+贪心选择就是最优解的问题,才能够使用贪心算法。
例子
一道谷歌算法题
一道泄露并遭禁用的谷歌面试题,背后玄机全解析
文章中给出了四种解决方案:
- 暴力求解
- 递归
- 缓存重复的子问题
- 动态规划,自底向上求解
实际上,文章Leetcode 935:骑士拨号器(超详细的解法!!!)给出了简化后的动态规划算法。这道题目就能够看出,分治向动态规划的转化。
算法导论中有讨论活动选择、最小生成树、赫夫曼编码等算法,阐述什么情况下适用贪心算法,比较关键的就是确定问题是最优子问题,确定问题是最优子问题的关键在于,选择关键参数。比如活动选择问题中,活动结束时间,就是关键参数,不是活动开始时间、活动结束时间。当然反证法证明最优子解+贪心选择就是最优解也是必要的。