问题描述
来自 Dasgupta 的算法:如果一个分治算法的运行时间用递归T(n)=aT(n/b)+O(n^d)
来描述,那么它的解是:
-
T(n)=O(n^d)
ifd>log_b(a)
-
T(n)=O(n^log_b(a))
ifd<log_b(a)
-
T(n)=O(n^d*log_2(n))
ifd=log_b(a)
其中每个子问题的大小在下一次递归调用中减少 b
,a
是分支因子,O((n/b^k)^d)
是在级别 {{} 上划分和组合子问题的时间1}} 对于每个子问题。
案例 1 和案例 2 很简单——它们取自在对递归树的每个级别所做的工作求和时形成的几何级数,即 k
。
案例 3 中的 a^k*O((n\b^k)^d)=O(n^d)*(a/b^d)^k
是从哪里来的?当 log_2(n)
时,比率 d=log_b(a)
等于 1,因此系列的总和是 a/b^d
,而不是 n^d*log_b(a)
解决方法
举一个更简单的例子,首先请注意 O(log n)、O(log137 n) 和 O(log16 n) 的意思相同。这样做的原因是,通过改变对数的基公式,对于任何固定常数 m,我们有
log_m n = log n / log m = (1 / log m) · log n = O(log n).
主定理假设 a、b 和 d 是常数。从对数的基公式的变化,我们有
在这个意义上,O(nd logb n) = O(nd log n),因为 b 是一个常数在这里。
请注意,看到一些东西写成 O(nd log2 n) 是不寻常的,因为这里的日志基数无关紧要,只是有所贡献到(已经隐藏的)常数因子。