从0开始学算法2:时间复杂度详解

一、算法的选择

我们都知道同一个问题有不同的算法解决,这些算法在运行时间、运行占用内存、代码易读性等方面都不相同,而在这些算法中,我们只能选择一种解决方案,这时判断选择哪个算法的依据是什么呢?

在这里,我们引入了时间复杂度和空间复杂度这两个概念作为选择适合算法的重要依据,一般对比算法的好坏基本上从它的时间复杂度和空间复杂度来综合判断就可以得出哪个更适合,复杂度通常来说越小越好。

算法的时间复杂度和空间复杂度的作用:时间复杂度是指执行这个算法所需要的计算工作量;而空间复杂度是指执行这个算法所需要的内存空间。时间和空间(即寄存器)都是计算机资源的重要体现,而算法的复杂性就是体现在运行该算法时的计算机所需的资源多少

二、时间复杂度概念

一个算法语句总的执行次数是关于问题规模N的某个函数,记为f(N),N称为问题的规模。语句总的执行次数记为T(N),当N不断变化时,T(N)也在变化,算法执行次数的增长速率和f(N)的增长速率相同。

则有T(N) = O(f(N)),这称作算法的渐进时间复杂度,简称时间复杂度。

说明:

  1. 算法的时间复杂度反映了程序执行时间随输入规模增长而增长的量级,在很大程度上能很好地反映出算法的优劣与否。
  2. 算法执行时间需要依据该算法编制的程序在计算机上执行运行时所消耗的时间来度量,度量方法有两种:事后统计方法和事前分析估算方法。因为事后统计方法更多地依赖计算机的硬件、软件等环境因素,有时容易掩盖算法本身的优劣,因此常采用事前分析估算的方法。
  3. 一个算法是由控制结构(顺序、分支、循环三种)和原操作(固有数据类型的操作)构成的,而算法时间取决于两者的综合效率。
  4. 一个算法花费的时间与算法中语句的执行次数成正比,执行次数越多,花费的时间就越多,其执行次数称为语句频度或时间频度,记为T(n)。
  5. 在时间频度中,n为问题的规模,当n不断变化时,它所呈现出来的规律,我们称为时间复杂度。
  6. 在各种算法中,若算法中的语句执行次数为一个常数,则时间复杂度为o(1),同时,若不同算法的时间频度不一样,但他们的时间复杂度却可能是一样的。比如:T(n)=n^2+2n+4 与 T(n)=4n2+n+8,他们的时间频度显然不一样,但他们的时间复杂度却是一样的,均为O(n2),时间复杂度只关注最高数量级,且与之系数也没有关系。

三、最坏时间复杂度和平均时间复杂度

最坏时间复杂度:
最坏情况下的时间复杂度称最坏时间复杂度,一般不特别说明,讨论的时间复杂度均是最坏情况下的时间复杂度。这样做的原因是:最坏情况下的时间复杂度是算法在任何输入实例上运行时间的上界,这就保证了算法的运行时间不会比最坏时间复杂度更长。

平均时间复杂度:
平均时间复杂度是指所有可能的输入实例均以等概率出现的情况下,算法的期望运行时间,设每种情况的出现的概率为pi,平均时间复杂度则为sum(pi*f(n)) 。

四、求解算法的时间复杂度的具体步骤

  1. 找出算法中的基本语句
    算法中执行次数最多的那条语句就是基本语句,通常是最内层循环的循环体。
  2. 计算基本语句的执行次数的数量级
    只需计算基本语句执行次数的数量级,这就意味着只要保证基本语句执行次数的函数中的最高次幂正确即可,可以忽略所有低次幂和最高次幂的系数。这样能够简化算法分析,并且使注意力集中在最重要的一点上:增长率。
  3. 用大Ο记号表示算法的时间性能
    将基本语句执行次数的数量级放入大Ο记号中,如果算法中包含嵌套的循环,则基本语句通常是最内层的循环体;如果算法中包含并列的循环,则将并列循环的时间复杂度相加。

举个简单的例子:

for(i=1;i<=n;i++){
     a++
};
for(i=1;i<=n;i++){
     for(j=1;j<=n;j++){
           a++;
     }
}

第一个for循环的时间复杂度为o(n),第二个for循环时间复杂度为o(n^2),则整个算法的时间复杂度为二者的和:
o(n^2+2)

o(1)表示基本语句的执行次数是一个常数,一般来说,只要算法中不存在循环语句,时间复杂度就为o(1)。

五、常用时间复杂度

常用的时间复杂度有以下七种,算法时间复杂度依次增加:O(1)常数型、O(log2 n)对数型、O(n)线性型、O(nlog2n)二维型、O(n2)平方型、O(n3)立方型、O(2^n)指数型.

下图表示随问题规模n的增大,算法执行时间的增长率。
在这里插入图片描述

六、特殊时间复杂度

  1. 二分查找
    因为每次的计算,都可以把查找的范围缩小一半,所以二分查找的时间复杂度为O(log2 N)。

  2. 斐波那契的递归算法
    因为每次的展开都要把当前的已知项再拆分成当前数目的两倍,所以斐波那契的递归算法时间复杂度为2^N。

斐波那契的时间复杂度算法如下图所示,计算n第N个斐波那契数的大小时,共需计算2^(N - 1)次。

在这里插入图片描述

七、常用排序算法的时间复杂度

在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章