递归算法的复杂度分析

 首先介绍3种表示复杂度的符号:

  1. Tight 上下界,f = tight(g)表示当输入大于某个整数时,存在常数c1和c2,使得 c1*g < f < c2*g ;
  2. Lower 下界, f = Lower(g)表示当n足够大的时候,存在c,使得 f<g *c;
  3. Upper上界, f = upper(g) 表示你足够大的时候,存在c使得 f> g * c;

算法复杂度分析就是求g的过程。通常来讲,算法的上界复杂度才有意义,即第二种,它表现了算法的优劣。

递归算法的复杂度求法不同于普通的算法,以归并排序为例,它的复杂度可以表示如下:

T(n) = 2 * T(n/2) +Lower(n)

它表示规模为n的算法所需时间是规模为n/2的两倍加上对整个数组进行扫描的时间。

 

最简单的求解算法是替换法,它由两个步骤组成:

  1. 猜测复杂度函数;
  2. 用猜测的函数替换递归表达式中的复杂度函数,并推导等式是否成立;

以上面的递归表达式为例,我们猜测复杂度为g=nlg(n),这也意味着当n最够大的时候f< n*lg(n)*c

现在用这个表达式替换 T(n/2),并推导出T(n)也符合这个猜测:

T(n)  = 2 * T(n/2) +Lower(n)

       <= 2 * n/2 *lg(n/2)*c+c2 * n

       = n *(lg(n) -1) *c + c2*n

      = n * lg(n)* c + (c2-c)* n

    < c * n * lg(n)

最后一步假设c2<c。由于这个两个常数都是自己选定的,所以可以做到这一点。

 

在使用替换方法时,最难的是猜测出表达式的形式 g。同时要注意到g中的c是常数,不能随着n而变化。有时可以通过变量替换的方法,将近似的表达式变换成熟悉的表达式。

 

使用递归树的方法可以较容易的猜测出表达式的形式。递归树的思想是,输入为n的复杂度是几个较小输入的复杂度的总和,这样一层一层的划分下去,会形成一个树。在树的每一层会增加复杂度,最后树的叶子节点是简单的操作,我们可以认为他的复杂度为常数c。这样我们只需要求的叶子节点的数量,以及树的层数,就可以计算出整个算法的复杂度。

以上面的归并排序算法为例,假设有n个节点,那么每个父亲两个孩子,所以有lg(n)层,每层复杂度为n,最后叶节点是n个。所以复杂度是n * lg(n) * c + n, 由于n的次数较低,所以略去。

 

利用递归树可以得到一个递归复杂度的通解,如下所示:

0=========(x / V)----+++++(x)+++++-------(x*V)^^^^^^^^^

首先给所有的递归复杂度一个统一的定义:

T(n)=aT(n/b)+f(n), a>1,b>1

那么x表示n的lg(a)/lg(b)次方。

V是n的一个未知的正数次方,任何正数都可以,0.1,0.0001,1,100。

上面那一排表示f(n)可能的复杂度,可以看到从左到右,逐渐增大。随着f(n)的复杂度不同,算法的复杂度也不一样。

  1. 在====区域,算法复杂度由x/v确定,T(n)=tight(x)
  2. 在++++区域,复杂度为 T(n)=Tight(X*lg(n))
  3. 在^^^^区域,复杂度由f(n)确定,T(n)=Tight(f(n))

最后一个有一个额外的限制,不过我还不明白为什么需要这个限制,这个限制是:a* f(n/b)<=c*f(n)其中c是小于1的常数。

推理很简单,设f(n)=n的y次方。

那么进入第三种情况说明,f(n)>x,也就是说y大于lg(a)/lg(b),也就说明a<b的y次方。

再回到a*f(n/b)<c f(n)上来,如果要满足题意,只需要则a* (n/b)的y次方<c*n的次方,那么只需要a<c*b的y次方。

由于a,b,y都是常数,必然可以求得一个c使得上面的等式成立。

 

最后是一个思考题,a[1...n]存放0到n共n+1个整数,只能进行一个操作"读取第i个元素的第j个bit",如何在Lower(n)的复杂度内找到丢失那个数。

我想到的方法是我们可以知道在0到31个bit上,所有整数共有多少个1是确定的。那么对n个数扫描32遍,肯定能发现在某几个位置上1丢失了,把这些1组合起来,就是我们丢失的数组。

不知道更好的解法是什么。

 

 

 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值