zoukankan      html  css  js  c++  java
  • 认识时间复杂度

      时间复杂度就是用来评价算法流程的标准,你可以随意脑补一个算法,它的正确性保证了后,你怎么去评价整个流程的好坏?就是用时间复杂度来评价的。介绍时间复杂度之前,我们先解释一下常数时间的操作,

    常数时间的操作:一个操作如果和数据量没有关系,每次都是固定时间内完成的操作,叫做常数操作。

      比如,数组寻址操作、加减乘除操作、位运算操作,这些是和样本的数据量无关,你每次完成这些操作都是固定时间。比如说机器每个数有多少位(long类型64位,int类型32位),做加减乘除肯定是固定时间,再比如数组的寻址,在计算机里面就是内存跳一下。这些东西都是常数操作。

      那么时间复杂度到底是什么?我们先看它的概念:

    时间复杂度为一个算法流程中,常数操作数量的指标。常用O(读作big O)来表示。具体来说,在常数操作数量的表达式中,只要高阶项,不要低阶项,也不要高阶项的系数,剩下的部分如果记为f(N),那么时间复杂度为O(f(N))。

      理解“只要高阶项,不要低阶项,也不要高阶项的系数”:

      有一个长度为n的无序数组,我们要将它排好序,设计的一种排序方式为:在0到n-1里遍历一次,找到min,然后放到0位置上;然后在1到n-1遍历一次,找到min放到1位置上....依次下去,直到把数组排好。

      这个复杂度怎么估计?第一次找到min时,过的是n个数,第二次找到min过的是n-1个数......最后排好需要过(n+n-1+n-2+...+2+1)个数,可以看出,这里常数操作数量的表达式是一个等差数列(n+1)n/2,可以写成:an²+bn+c。
      根据“只要高阶项,不要低阶项,也不要高阶项的系数”,这个时间复杂度就是O(n²)。

      评价一个算法流程的好坏,先看时间复杂度的指标,然后再分析不同数据样本下的实际运行时间,也就是常数项时间。

      下面通过一个简单的例子来理解时间复杂度:

      一个有序数组A,另一个无序数组B,请打印B中的所有不在A中的数,A数组长度为N,B数组长度为M。

      【算法流程1】:对于数组B中的每一个数,都在A中通过遍历的方式找一下;

    for(int i=0;i<M-1;i++){
        for(int j=0;j<N-1;j++){
          ...
      }      
    }

      任何一个M中的每一个数都要遍历N次,所以整体常数操作的表达式为f(M,N) = M * N,所以时间复杂度为O(M*N)

      【算法流程2】:对于数组B中的每一个数,都在A中通过二分的方式找一下;

      B中一共有M个数,每找一个数都通过二分的方式,二分查找常数操作量约为logN,因此B中每一个数确定在A中是否存在的代价为O(logN),所以时间复杂度为O(M*logN)

      【算法流程3】:先把数组B排序,然后用类似外排的方式打印所有不在A中出现的数;

      思路:

      

      第一步:数组B排序的代价为:O(M*logM),

      第二步:类似外排的方式,a最多指N个数,b最多指M个数,当a和b有一个到达终点,整个流程就结束,最差的情况就是a指N个数,b指M个数。所以复杂度为O(N+M)

      由于样本量不确定,所以此处的复杂度为O(M*logM)+O(N+M)。如果N很小,复杂度为O(M*logM);如果M很小,复杂度就变为O(N+M)了。 

      【结论】

      综合上述3个算法,可以看出算法1是最差的。如果A数组很短,B数组很长,算法2更好;反之,算法3更好。

  • 相关阅读:
    vue项目搭建
    iview在ie9及以上的兼容问题解决方案
    中山大学校队内部选拔赛试题试题2【New Year Gift】--------2015年2月8日
    中山大学校队选拔赛第二试题试题3【Compressed suffix array】-------2015年2月8日
    ZOJ2812------2015年2月4日
    C++STL泛型编程基础知识讲解--------2015年2月3日
    中山大学校队选拔赛第一章题4【简单数迷Simple Kakuro】-------2015年1月28日
    UVALive
    UVA11375【火柴拼数Matches】-------2015年1月27日
    递推关系的运用加简单DP【UVA11137Ingenuous Cubrency】-------2015年1月27日
  • 原文地址:https://www.cnblogs.com/yft-javaNotes/p/10669260.html
Copyright © 2011-2022 走看看