《算法导论》学习(五)---- 分治策略(递归)的时间复杂度求解


前言

求解递归式的时间复杂度是学习算法很重要的一部分
本文主要讲解了利用“主方法”来求解递归式的时间复杂度,并对其进行了一定程度上的逻辑证明


一、用主方法求解递归式

(1)递归式的一般形式

T ( n ) = a T ( n / b ) + f ( n ) ,其中 a ⩾ 1 和 b ⩾ 1 是常数 T(n)=aT(n/b)+f(n), 其中a\geqslant1和b\geqslant1是常数 T(n)=aT(n/b)+f(n),其中a1b1是常数
该一般形式描述的是分治策略算法的运行时间:

该算法将规模为n的问题分解为a个子问题,每个子问题规模为n/b,其中a和b都是常数。a个子问题递归地进行求解,每个花费时间 T ( n / b ) T(n/b) T(n/b)。函数 f ( n ) f(n) f(n)包含了问题分解和子问题解合并的代价。

(2)主方法

令 a ⩾ 1 和 b ⩾ 1 是常数, f ( n ) 是一个函数, T ( n ) 是定义在非负整数上的递归式: 令a\geqslant1和b\geqslant1是常数,f(n)是一个函数,T(n)是定义在非负整数上的递归式: a1b1是常数,f(n)是一个函数,T(n)是定义在非负整数上的递归式:
T ( n ) = a T ( n / b ) + f ( n ) T(n)=aT(n/b)+f(n) T(n)=aT(n/b)+f(n)
其中我们将 n / b 解释为 ⌊ n / b ⌋ 或者 ⌈ n / b ⌉ 。那么 T ( n ) 有如下渐进界: 其中我们将n/b解释为\lfloor n/b\rfloor或者 \lceil n/b\rceil。那么T(n)有如下渐进界: 其中我们将n/b解释为n/b或者n/b。那么T(n)有如下渐进界:
1. 若对某个常数 ε > 0 有 f ( n ) = O ( n l o g b a − ε ) ,则 T ( n ) = Θ ( n l o g b a ) 1.若对某个常数\varepsilon>0有f(n)=O(n^{{log_{b}a}-\varepsilon}),则T(n)=\Theta(n^{log_ba}) 1.若对某个常数ε>0f(n)=O(nlogbaε),则T(n)=Θ(nlogba)
2. 若 f ( n ) = Θ ( n l o g b a ) ,则 T ( n ) = Θ ( n l o g b a l g n ) 2.若f(n)=\Theta(n^{log_{b}a}),则T(n)=\Theta(n^{log_{b}a}lgn) 2.f(n)=Θ(nlogba),则T(n)=Θ(nlogbalgn)
3. 若对某个常数 ε > 0 有 f ( n ) = Ω ( n l o g b a + ε ) , 且对某个常数 c < 1 和所有足够大的 n 有 a f ( n / b ) ⩽ c f ( n ) ,则 T ( n ) = Θ ( f ( n ) ) 3.若对某个常数\varepsilon>0有f(n)=\Omega(n^{log_b{a}+\varepsilon}),且对某个常数c<1和所有足够大的n有 af(n/b)\leqslant cf(n),则T(n)=\Theta(f(n)) 3.若对某个常数ε>0f(n)=Ω(nlogba+ε),且对某个常数c<1和所有足够大的naf(n/b)cf(n),则T(n)=Θ(f(n))

(3)理解主方法

对于三种情况的每一种,我们将函数 f ( n ) f(n) f(n)与函数 n l o g b a n^{log_ba} nlogba进行比较。直觉上,两个函数较大者决定了递归式的解。若函数 n l o g b a n^{log_ba} nlogba更大,如情况1,则解为 T ( n ) = Θ ( n l o g b a ) T(n)=\Theta(n^{log_ba}) T(n)=Θ(nlogba)。如函数 f ( n ) f(n) f(n)更大,如情况3,则解为 T ( n ) = Θ ( f ( n ) ) T(n)=\Theta(f(n)) T(n)=Θ(f(n))。若两个函数大小相当,如情况2,则乘上一个对数因子,解为 T ( n ) = Θ ( n l o g b a l g n ) = Θ ( f ( n ) l g n ) T(n)=\Theta(n^{{log_{b}a }}lgn)=\Theta(f(n)lgn) T(n)=Θ(nlogbalgn)=Θ(f(n)lgn)

再此直觉之外,我们需要了解: f ( n ) 与 n l o g b a 的比较,是在多项式意义上的比较,需要渐进小于,大于 f(n)与n^{log_ba}的比较,是在多项式意义上的比较,需要渐进小于,大于 f(n)nlogba的比较,是在多项式意义上的比较,需要渐进小于,大于

那么我们可以发现,这三种情况并未覆盖 f ( n ) f(n) f(n)的所有可能性。情况1与情况2,情况2与情况3之间都有间隙,这归根结底是多项式层面的小于大于导致的。这时就不能通过主方法来求解递归式。

二、利用主方法求解一些实例

(1)例子1

T ( n ) = 9 T ( n / 3 ) + n T(n)=9T(n/3)+n T(n)=9T(n/3)+n
对于递归式,我们有: a = 9 , b = 3 , f ( n ) = n , 因此 n l o g b a = n l o g 3 9 = Θ ( n 2 ) a=9,b=3,f(n)=n,因此n^{log_ba}=n^{log_39}=\Theta(n^2) a=9,b=3,f(n)=n,因此nlogba=nlog39=Θ(n2),又因为有 f ( n ) = n = O ( n l o g 3 9 − ε ) f(n)=n=O(n^{{log_39}-\varepsilon}) f(n)=n=O(nlog39ε),所以满足主方法的情况1,因此 T ( n ) = Θ ( n 2 ) T(n)=\Theta(n^2) T(n)=Θ(n2)

(2)例子2

T ( n ) = T ( 2 n / 3 ) + 1 T(n)=T(2n/3)+1 T(n)=T(2n/3)+1
对于递归式,我们有: a = 1 , b = 3 / 2 , f ( n ) = 1 , 因此 n l o g b a = n l o g 3 2 1 = Θ ( 1 ) a=1,b=3/2,f(n)=1,因此n^{log_ba}=n^{log_{\frac{3}{2}}1}=\Theta(1) a=1,b=3/2,f(n)=1,因此nlogba=nlog231=Θ(1),又因为有 f ( n ) = 1 = Θ ( 1 ) f(n)=1=\Theta(1) f(n)=1=Θ(1),所以满足主方法的情况2,因此 T ( n ) = Θ ( l g n ) T(n)=\Theta(lgn) T(n)=Θ(lgn)

(3)例子3

T ( n ) = 3 T ( n / 4 ) + n l g n T(n)=3T(n/4)+nlgn T(n)=3T(n/4)+nlgn
对于递归式,我们有: a = 3 , b = 4 , f ( n ) = n l g n , 因此 n l o g b a = n l o g 4 3 = Θ ( n 0.793 ) a=3,b=4,f(n)=nlgn,因此n^{log_ba}=n^{log_43}=\Theta(n^{0.793}) a=3,b=4,f(n)=nlgn,因此nlogba=nlog43=Θ(n0.793),又因为有 f ( n ) = n l g n = Ω ( n l o g 4 3 + ε ) f(n)=nlgn=\Omega(n^{log_43+\varepsilon}) f(n)=nlgn=Ω(nlog43+ε),如果满足正则条件成立,就可以满足主方法的情况3。当n足够大的时候,对于 c = 3 / 4 , a f ( n / b ) = 3 ( n / 4 ) l g ( n / 4 ) ⩽ ( 3 / 4 ) n l g n = c f ( n ) c=3/4,af(n/b)=3(n/4)lg(n/4)\leqslant(3/4)nlgn=cf(n) c=3/4,af(n/b)=3(n/4)lg(n/4)(3/4)nlgn=cf(n)。因此 T ( n ) = Θ ( n l g n ) T(n)=\Theta(nlgn) T(n)=Θ(nlgn)

(4)例子4

T ( n ) = 2 T ( n / 2 ) + n l g n T(n)=2T(n/2)+nlgn T(n)=2T(n/2)+nlgn
对于递归式,我们有: a = 2 , b = 2 , f ( n ) = n l g n , 因此 n l o g b a = n l o g 2 2 = Θ ( n ) a=2,b=2,f(n)=nlgn,因此n^{log_ba}=n^{log_22}=\Theta(n) a=2,b=2,f(n)=nlgn,因此nlogba=nlog22=Θ(n)。但是因为 f ( n ) = n l g n f(n)=nlgn f(n)=nlgn并不是渐进大于n。因为 f ( n ) n l o g b a = l g n , 都渐进小于 n ε \frac{f(n)}{n^{log_ba}}=lgn,都渐进小于n^{\varepsilon} nlogbaf(n)=lgn,都渐进小于nε。因此递归式落入了情况2和情况3之间的间隙,无法用主方法解决。

(5)例子5

T ( n ) = 2 T ( n / 2 ) + Θ ( n ) T(n)=2T(n/2)+\Theta(n) T(n)=2T(n/2)+Θ(n)
这个递归式是最大和子数组问题归并排序的算法运行时间描述。这里我们运用主方法求解:
a = 2 , b = 2 , f ( n ) = Θ ( n ) , n l o g b a = n l o g 2 2 = Θ ( n ) = f ( n ) a=2,b=2,f(n)=\Theta(n),n^{log_ba}=n^{log_22}=\Theta(n)=f(n) a=2,b=2,f(n)=Θ(n),nlogba=nlog22=Θ(n)=f(n),因此满足情况2,因此:
T ( n ) = Θ ( n l g n ) T(n)=\Theta(nlgn) T(n)=Θ(nlgn)

(6)例子6

T ( n ) = 8 T ( n / 2 ) + Θ ( n 2 ) T(n)=8T(n/2)+\Theta(n^2) T(n)=8T(n/2)+Θ(n2)
这个是矩阵乘法的普通递归算法的时间描述:
a = 8 , b = 2 , f ( n ) = Θ ( n 2 ) , 那么 n l o g b a = n l o g 2 8 = Θ ( n 3 ) , 又因为 f ( n ) = O ( n l o g 2 8 − ε ) a=8,b=2,f(n)=\Theta(n^2),那么n^{log_ba}=n^{log_28}=\Theta(n^3),又因为f(n)=O(n^{log_28-\varepsilon}) a=8,b=2,f(n)=Θ(n2),那么nlogba=nlog28=Θ(n3),又因为f(n)=O(nlog28ε),因此, T ( n ) = Θ ( n 3 ) T(n)=\Theta(n^3) T(n)=Θ(n3)

(7)例子7

T ( n ) = 7 T ( n / 2 ) + Θ ( n 2 ) T(n)=7T(n/2)+\Theta(n^2) T(n)=7T(n/2)+Θ(n2)
这个是矩阵乘法的Strassen(斯特拉森)算法的时间描述:
a = 7 , b = 2 , f ( n ) = Θ ( n 2 ) , 那么 n l o g b a = n l o g 2 7 , 又因为 2.80 < l g 7 < 2.81 , 因此若 ε = 0.8 , 那么有 f ( n ) = O ( n l o g 2 7 − ε ) a=7,b=2,f(n)=\Theta(n^2),那么n^{log_ba}=n^{log_27},又因为2.80<lg7<2.81,因此若\varepsilon=0.8,那么有f(n)=O(n^{log_27-\varepsilon}) a=7,b=2,f(n)=Θ(n2),那么nlogba=nlog27,又因为2.80<lg7<2.81,因此若ε=0.8,那么有f(n)=O(nlog27ε),因此, T ( n ) = Θ ( n l g 7 ) T(n)=\Theta(n^{lg7}) T(n)=Θ(nlg7)


总结

除了“主方法”之外,还有代入法,递归树两大方法。
例子5,6,7涉及的算法可以参考文章:
链接: 《算法导论》学习(三)---- 最大和子数组问题的分治方法
链接: 《算法导论》学习(四)---- 矩阵乘法的Strassen(斯特拉森)算法

  • 5
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
大常用算法是动态规划、分治、递归、贪心和回溯。 动态规划是一种将问题分解成子问题并保存子问题解的方法。通过求解子问题,可以逐步推导出原始问题的解。动态规划通常用于求解最优化问题,例如最长公共子序列、最短路径等。 分治是将原问题划分成多个相互独立的子问题,然后通过递归的方式求解子问题,并将子问题的解合并成原问题的解。分治算法常用于排序、快速幂等问题。 递归是通过函数调用自身来解决问题的方法递归算法在问题定义可以被分解为较小规模或更简单情况的时候很有用。例如,计算一个数的阶乘,就可以使用递归实现。 贪心算法是一种选择当前最优策略的方法,即在每一步选取最优解,最终得到全局最优解的算法。贪心算法通常用于解决无后效性的问题,例如最小生成树、哈夫曼编码等。 回溯是一种通过穷举搜索所有可能的解空间,找到满足条件的解的方法。回溯算法在解决组合问题、排序问题、子集和问题等方面很有效。回溯算法通过递归的方式逐步构建解,当发现当前解不满足条件时,会回退到上一步继续搜索其他可能的解。 这种常用算法在不同的问题领域中都有广泛应用,每种算法都有自己的特点和适用范围。在解决具体问题时,可以根据问题的性质和要求选择最适合的算法进行求解

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SigmaBull

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值