跳到主要内容

复杂度

参考资料

定义

时间复杂度

衡量一个算法的快慢,一定要考虑数据规模的大小。

所谓数据规模,一般指输入的数字个数、输入中给出的图的点数与边数等等。一般来说,数据规模越大,算法的用时就越长。

而在算法竞赛中,我们衡量一个算法的效率时,最重要的不是看它在某个数据规模下的用时,而是看它的用时随数据规模而增长的趋势,即 时间复杂度

空间复杂度

类似地,算法所使用的空间随输入规模变化的趋势可以用 空间复杂度 来衡量。

渐进符号

  • Θ\Theta 符号:确界
  • OO 符号:上界
  • Ω\Omega 符号:下界
  • oo 符号:严格上界
  • ω\omega 符号:严格下界

常见性质

  • f(n)=Θ(g(n))    f(n)=O(g(n))f(n)=Ω(g(n))f(n) = \Theta(g(n))\iff f(n)=O(g(n))\land f(n)=\Omega(g(n))
  • f1(n)+f2(n)=O(max(f1(n),f2(n)))f_1(n) + f_2(n) = O(\max(f_1(n), f_2(n)))
  • f1(n)×f2(n)=O(f1(n)×f2(n))f_1(n) \times f_2(n) = O(f_1(n) \times f_2(n))
  • a1,logan=O(log2n)\forall a \ne 1, \log_a{n} = O(\log_2 n)
提示

由换底公式可以得知,任何对数函数无论底数为何,都具有相同的增长率,因此渐进时间复杂度中对数的底数一般省略不写。

示例
for(int i=1;i<n;i++)
{
for(int j=1;j<=n-i;j++)
{
if(a[j]>a[j+1])swap(a[j],a[j+1]);
}
}

时间复杂度 Θ(n2)\Theta(n^2)

主定理

主定理(Master Theorem)可以快速求得关于递归算法的复杂度。

假设有递归关系式:

T(n)=aT(nb)+f(n)T(n)=aT\left(\frac{n}{b}\right)+f(n)

其中 nn 为问题规模,aa 为递归的子问题数量,nb\frac{n}{b} 为每个子问题的规模,f(n)f(n) 为递归以外进行的计算工作。那么:

T(n)={Θ(nlogba)f(n)=O(nlogb(a)ϵ),ϵ>0Θ(f(n))f(n)=Ω(nlogb(a)+ϵ),ϵ0Θ(nlogbalogk+1n)f(n)=Θ(nlogbalogkn),k0T(n)= \begin{cases} \Theta(n^{\log_b a}) & f(n) = O(n^{\log_b (a)-\epsilon}),\epsilon > 0 \\ \Theta(f(n)) & f(n) = \Omega(n^{\log_b (a)+\epsilon}),\epsilon\ge 0 \\ \Theta(n^{\log_b a}\log^{k+1} n) & f(n)=\Theta(n^{\log_b a}\log^k n),k\ge 0 \end{cases}
示例
T(n)=2T(n2)+Θ(1)T(n)=2T\left(\frac{n}{2}\right)+\Theta(1)

时间复杂度 Θ(n)\Theta(n)