算法时间复杂度之分治与递归
算法是解决问题的办法或法则,而“速度”就是算法之魂,在计算机中所谓的“速度”就是=时间+空间。在大家初期的算法学习中,往往感觉算法这东西摸不着头脑,会感觉:它为什么会这么用,这种用法究竟有什么不同,我自己的解法就不好吗?所以要想解决这种困惑,要想真正的理解算法之道,就必须要对算法的复杂度进行分析。
因为算法的复杂度与时间效率有很大的关系,所以我们分析算法往往基于对时间复杂度的分析。
今天这一节,我们先讲讲递归问题的算法分析。
算法核心:一般来讲,分治策略将一个大的复杂的问题划分为a个同样的子问题,这些子问题的大小为n/b。如果一直递归分解下去,我们获得的算法时间复杂性的递归表达式为:
Tn=a+T(n/b)+f(n)
这里的b是每次分解时间问题规模减小的因子,a是每次分解时产生的子问题个数,是分解出(和合并)a个大小为n/b的子问题的成本。很显然,a>=1,b>1,并且f的渐进趋势为正。(如果该函数渐进表现为负会是什么情况?)注意,如果b<=1,则说明这种分治完全失败,因为分解出来的子问题规模与原问题相当或超过了原问题!
这样,求解一个分而治之算法的时间效率就是求解上述递归表达式。那么上述递归表达式的解是什么呢?
Eg:有一段程序:
voidfun(int a[],int n,int k)
{
int i;
if(k==n-1)
{
for(i=0;i<n;i++)
cout<<a[i];
}
else
{
for(i=k;i<n;i++)
a[i]=a[i]+i*i;
fun(a,n,k+1);
}
}
因为每次分解只有一个fun()函数,所以a=1;
因为每次k只加1,所以n/b=(n-1)/1;
因为每次分解都有一个i从k到n的循环,所以f(n)=n-k;
综上:
n ,当k=n-1;
T(n)=
(n-k)+T(k+1) ,其他情况;
所以大家基于这个求递归的复杂度的算法,可以进一步检验此类算法的效率。