算法基础知识——分治策略
目录:
- 基础知识
- 算法依赖因素
- 输入规模、运行时间
- 渐近记号(O、θ、Ω)
- 分治策略
- 分解、解决、合并
- 代入法、递归树法、主方法
- 经典问题
- 最大子数组问题
- Strassen矩阵乘法问题
- 应用实例
- n的阶乘【清华大学】
- 递归和动态规划-汉诺塔II【2016校招真题在线编程】
- 全排列【北京大学】
- 杨辉三角【西北工业大学】
- Fibonacci【上海交通大学】
- 二叉树【北京大学】
- 2的幂次方【上海交通大学】
一、基础知识
1、一个算法的依赖因素:
- 待排序项数;
- 这些项已被稍微排序的程度;
- 关于项值的可能限制;
- 计算机的体系结构;
- 存储设备的种类(主存、磁盘、磁带等)。
2、输入规模:输入中的项数。
3、运行时间:执行的基本操作数或步数。
4、渐进记号:
- θ(g(n)) :
- 定义:存在正常量c1、c2和n0,使得对所有n ≥ n0,有0 ≤ c1g(n) ≤ f(n) ≤ c2g(n),其中f(n)在一个常量因子内等于g(n),g(n)是f(n)的一个渐近紧确界(asymptotically tight bound)。
- 每个成员f(n) ∈ θ(g(n))均渐近非负。
- θ记号渐近地给出了一个函数的上界和下界。
- O(g(n)):
- 定义:存在正常量c和n0,使得所有n ≥ n0,有0 ≤ f(n) ≤ cg(n),g(n)为渐近上界。
- θ(g(n)) 包含于 O(g(n))。
- O记号为函数给出一个在常量因子内的上界。
- o记号(小og(n))中,界0 ≤ f(n) ≤ cg(n)对所有常量c>0成立
- Ω(g(n)):
- 定义:存在正常量c和n0,使得所有n ≥ n0,有0 ≤ cg(n) ≤ f(n),g(n)为渐近下界。
- Ω记号为函数给出一个在常量因子内的下界。
- ω记号(小ωg(n))中,界0 ≤ cg(n) ≤ f(n)对所有常量c>0成立
二、分治策略
1、递归步骤:
- 分解(Divide):将问题划分为一些子问题,子问题的形式与原问题一样,只是规模更小;
- 解决(Conquer):递归地求解出子问题。如果子问题的规模足够小,则停止递归,直接求解;
- 合并(Combine):将子问题的解组合成原问题的解。
2、递归情况与基本情况:
- 递归情况(recursive case):当子问题足够大,需要递归求解时,称之为递归情况。
- 基本情况(base case):当子问题足够小,不再需要递归时,即递归已经“触底”,称之为基本情况。
3、求解递归式的方法:
- 代入法:
- 定义:猜测一个界,然后用数学归纳法证明这个界是正确的。
- 步骤:
- 猜测解的形式;
- 用数学归纳法求出解中的常数,并证明解释正确的。
- 示例:T(n) = 2T(⌊n / 2⌋) + n
- 猜测解的形式为:T(n) = O(nlogn)
- 设T(n) ≤ knlogn,假设此上界对所有正数m < n成立,当m = ⌊n / 2⌋时,有T(⌊n / 2⌋) ≤ k⌊n / 2⌋log(⌊n / 2⌋⌋) ,将其代入递归式,得:T(n) ≤ 2k⌊n / 2⌋log(⌊n / 2⌋) + n ≤ knlog(n / 2) + n = knlogn - knlog2 + n = knlogn - kn + n = knlogn - (k - 1)n ≤ knlogn,其中n ≥ 1时,最后一步成立。
- 递归树法:
- 定义:将递归式转换成一棵树,其结点表示不同层次的递归调用产生的代价。然后采用边界和技术来求解递归式。
- 步骤:
- 每个结点表示一个单一子问题的代价,子问题对应某次递归函数调用;
- 将树中的每层中的代价求和,得到每层代价,然后将所有层的代价求和,得到所有层次的递归调用的总代价。
- 主方法:T(n) = aT(n / b) + f(n)
- 定义:将规模为n的问题分解为a个子问题,每个子问题的规模是原问题规模的n / b,分解和合并步骤总共花费时间为f(n)。
- 主定理:
- 示例: