算法之时间复杂度

      在 计算机科学 中, 算法 的时间复杂度是一个 函数 ,它定量描述了该算法的运行时间。这是一个关于代表算法输入值的 字符串 的长度的函数。时间复杂度常用 大O符号 表述,不包括这个函数的低阶项和首项系数。使用这种方式时,时间复杂度可被称为是 渐近 的,它考察当输入值大小趋近无穷时的情况。

这样用大写O()来体现算法时间复杂度的记法,我们称之为大O记法。一般情况下,随着n的增大,T(n)增长最慢的算法为最优算法。

 

    举例,如果一个算法对于任何大小为n的输入,它至多需要5n3+3n的时间运行完毕,那么它的渐近时间复杂度是O(n3)

注意:

   时间复杂度计算过程中,是最终会去掉这个函数的低阶项和首项系数的。(这也就是为什么5n3+3n 会最终化简为n3

 

 

举例

一:O(1) 常数阶
     Temp=i;i=j;j=temp;  

以上三条单个语句的频度均为1,该程序段的执行时间是一个与问题规模n无关的常数。算法的时间复杂度为常数阶,记作T(n)=O(1)。如果算法的执行时间不随着问题规模n的增加而增长,即使算法中有上千条语句,其执行时间也不过是一个较大的常数。此类算法的时间复杂度是O(1)

 

二: O(n) 线性阶

通常,如果某个循环结构以线性方式运行n,并且循环体的时间复杂度都是O(1),那么该循环的复杂度就是O(n).

 

for(int i = 0; i < n; i++){
    //一些列复杂度为O(1)的步骤....
 }

 

即使,该循环跳过某些常数部分,只要跳过的部分是线性的,那么该循环体的时间复杂度仍就是O(n).
比如

  int count = 1;
  while(count < n){
    count += 2;
    //一些列复杂度为O(1)的步骤....
  }

    时间复杂度还是O(n)

 

 

三:O( log2n) 对数级

 int count = 1;
  while(count < n){
    count *= 2;
     //一些列复杂度为O(1)的步骤....
  }

    该循环2^f(n)<=n;  f(n)<=log2取最大值f(n)= log2n,  T(n)=O(log2n) 

 

四:循环嵌套复杂度分析

 

 for(int count1 = 0; count1 < n; count1++){
    for(int count2 = 0; count2 < n; count2++){
         //一些列复杂度为O(1)的步骤....
    }
  }

     在这种情况下应该 先计算内层循环的时间复杂度,然后用内层的复杂度乘以外层循环的次数。 最内层循环体的时间复杂度都是O(1)所以循环n次也就是O(n) 在乘以最外层forn次。所以得出结论 2层嵌套循环的时间复杂度 = O(1) * n*n = O(n2)

 

算法优化:

   计算1 + 2 + 3 + 4 + ......  + n =?  ,通过程序实现,并标出算法的时间复杂度。

 

Java解法一

   public int method01(int n){
         int sum = 0;
         for(int i=1;i<=n;i++){
             sum += i;
         }
         return sum;
    }

    时间复杂度: O(n)

 

德国数学家高斯曾经在他约9岁的时候就提过自己的解法:

     SUM = 1   + 2  + 3  + 4  + ......  + 100

     SUM = 100 + 99 + 98 + 97 + ......  + 1

     SUM + SUM = 2*SUM = 101 + 101 + 101 + .... + 101        //正好 100 101

     SUM =  100*101/2 = 5050


Java解法二

  public int method02(int n){
        int sum = 0;
        sum = (n*(n-1))/2;       
        return sum;
   }

    时间复杂度: O(1)

 

  从时间复杂度上来年,解法二比解法一更高效

 

 

常见的算法时间复杂度由小到大依次为:

Ο(1)Ο(log2n)Ο(n)Ο(nlog2n)Ο(n2)Ο(n3){Ο(2n)Ο(n!)<O(nn)}

 

    最后三项用大括号把他们括起来是想要告诉大家,如果日后大家设计的算法推导出的O是大括号中的这几位,那么趁早放弃这个算法,在去研究新的算法出 来吧。因为大括号中的这几位即便是在 n 的规模比较小的情况下仍然要耗费大量的时间,算法的时间复杂度大的离谱,基本上就是不可用状态

 

 

参考资料:

http://www.cnblogs.com/sakorn/archive/2007/05/18/751661.html

http://www.douban.com/note/91775206/

http://blog.csdn.net/xingqisan/article/details/3206303

http://www.cnblogs.com/yanng/articles/2178710.html

 

 

你可能感兴趣的:(java,算法,时间复杂度,效率)