分治算法 | 贪心算法 | 动态规划 | 回溯法 | |
---|---|---|---|---|
问题类型 | 通用问题 | 优化问题 | 优化问题 | 通用问题 |
子问题结构 | 独立,类型相同 | 只考虑当前子问题 | 子问题可能重复 | 无 |
子问题在最优解里 | 全部 | 部分 | 全部 | 无 |
选择与求解次序 | 先选择后解决子问题 | 先选择后解决子问题 | 先选择后解决子问题 | 用深度搜索来解决问题 |
分治算法
基本思想:
分治法(Divide and Conquer),字面意思就是分而治之,即 将问题简化为“分”和“治”两个步骤。当遇到一个复杂的问题(规模为N),可以根据问题的性质将其分解为两个或者多个规模较小的子问题(加上一共有K个子问题)。- 具体操作:
- 将复杂问题拆解为子问题;
- 将简单子问题求解;
- 将子问题的解合并为原问题的解。
适用性:
通常来说可以适用分治法的问题是问题规模小时容易解决,而且分解后的子问题为性质相同的独立问题。
在算法题中如果出现了O(logn)的复杂度,都可以先考虑一下分治法。
-
算法应用:
快速幂,求\(a^n\)(n为偶数)
用算法设计的思想,不全部计算出来求3的96次方的第十位数值。
\(3^{96}=9^{48}=81^{24}=6561^{12}=...\)
\(A^n=A^{n/2}*A^{n/2}\),一直递归下去,其间就可以省略很多不必要的计算,得到O(logn)的方法。
贪心算法
基本思想:
贪心算法(Greedy algorithm),该算法的名字很形象地说明该算法的特点,将问题分为一个个局部子问题之后,求解每个子问题的时候,不考虑子问题当前的解对于整个问题的影响,只考虑当前情况的最优解,即 当前子问题的解不会对后序的状态造成影响。- 具体操作:
- 将复杂问题分解为多个子问题;
- 子问题的解是当前所有解中的最优解;
-
将所有子问题的解合并为原问题的解。
注意:贪心算法与动态规划算法较为相似,其中一个很关键的区别是贪心算法是不可取消的,自顶向下地求出子问题的当前最优解;而动态规划是每步做出的选择都依赖于子问题的解。
适用性:
动态规划
基本思想:
动态规划算法与之前的分治和贪心算法有点相似,都是将一个规模大的问题转化为几个小的问题,通过解决小问题来得到整体的解。动态规划的核心问题是问题的状态的定义与状态转移房产的求解。动态规划的关键就在于将重复出现的子问题在第一次求解之后就将其保存起来,以后再遇到时不用重复求解。动态规划是按照自底向上的方式计算最优解。- 具体操作:
- 将问题分解为不同的子问题;
- 定义状态找出初始状态;
- 状态转移方程的求解;
- 求出问题最终答案。
适用性:
当题目求解的是最大值/最小值,可行与否或者方案总数时,考虑使用动态规划算法。