简介
分析递归的时间复杂度时通常需要用到主定理,我之前一直当作黑盒去用它,但是越来越想了解一下这个定理是如何证明的,发现证明过程只用到了等比级数与对数的相关公式,这里记录一下。
主定理
对于递归式 T(n)=aT(bn)+f(n) 的时间复杂度,主定理可以求解下面四种情况:
- 当 f(n)=O(nlogba−ϵ) 其中 ϵ>0 为常数,那么 T(n)=Θ(nlogba)。
- 当 f(n)=Θ(nlogba),那么 T(n)=Θ(nlogbalogn)。
- 当 f(n)=Ω(nlogba+ϵ),对于常数 0<c<1 和所有足够大的 n 满足 af(bn)≤cf(n) 那么 T(n)=Θ(f(n))。
- 当 f(n)=Θ(nlogbalogkn) 其中 k>0 为常数,那么 T(n)=Θ(nlogbalogk+1n)。
复习一下复杂度记号:O 代表上界,Θ 代表同级,Ω 代表下界。由于本文是复杂度相关证明,所以就严谨一点。
证明
首先画出递归树,这里贴上算法导论第四版原版 109 页中的图:
设根结点深度为 0,可以看出深度为 j 的层有 aj 个结点,每个结点的值是 f(n/b) 那么此层之和为 ajf(n/bj),并且最后一层有 Θ(alogbn)=Θ(nlogba) 个结点,所以所有结点之和就是:
Θ(nlogba)+j=0∑logbnajf(bjn)
令 g(n)=∑j=0logbnajf(n/bj),下面分类讨论。
Case I
当 f(n)=O(nlogba−ϵ),代入:
g(n)=Oj=0∑logbnaj(bjn)logba−ϵ=Oj=0∑logbnaj(ajnlogba−ϵ(bϵ)j)=Onlogba−ϵj=0∑logbn(bϵ)j=O(nlogba−ϵbϵ−1nϵ−1)=O(nlogba)
因此 T(n)=Θ(nlogba), 证毕。
Case II
当 f(n)=Θ(nlogba),代入:
g(n)=Θj=0∑logbnaj(bjn)logba=Θj=0∑logbnajajnlogba=Θ(nlogbalogbn)=Θ(nlogbalogn)
因此 T(n)=Θ(nlogbalogn),证毕。
Case III
当 f(n)=Ω(nlogba+ϵ),对于常数 0<c<1 和所有足够大的 n 满足 af(bn)≤cf(n),当 f(n)=nlogba+ϵ 时,这实际上是要求:
a(bn)logba+ϵbϵ1≤cnlogba+ϵ≤c
也就是要求 b>1,然后就可以用等比级数放缩:
g(n)=j=0∑logbnajf(bjn)≤j=0∑logbncjf(n)≤f(n)j=0∑∞cj=f(n)(1−c1)=O(f(n))
根据 g(n) 的定义,g(n)=f(n)+af(n/b)+⋯≥f(n),所以 g(n)=Θ(f(n)),因此 T(n)=Θ(f(n)),证毕。
Case IV
当 f(n)=Θ(nlogbalogkn) 其中 k>0 为常数,代入:
g(n)=Θj=0∑logbnaj(bjn)logbalogkbjn=Θnlogbaj=0∑logbnlogkbjn=Θ(nlogbalogknlogbn)=Θ(nlogbalogk+1n)
因此 T(n)=Θ(nlogbalogk+1n),证毕。
总结
我的记忆方法:对于递归式 T(n)=aT(bn)+f(n),将 f(n) 与 nlogba 比较,相等时为 Θ(nlogbalogn),否则当 f(n) 为多项式时,由两者较大的决定复杂度。对于 f(n)=Θ(nlogbalogkn) 特殊记忆。
仅当 f(n) 与 nlogba 相差 nϵ 阶或者 logϵn 阶时,其中 ϵ 为常数,才能用使用主定理求解复杂度,否则需要用到 Akra-Bazzi 定理,本文就不涉及了,因为我不会。