复杂度分析-时间复杂度

310 阅读2分钟

什么是复杂度分析

 复杂度分析就是分析、统计代码的执行效率和资源消耗。

为什么要用复杂度分析

一般情况下可以通过调试代码监控数据的性能、运行时间、以及其他。但是这种方法有两个缺点:
    1、对测试环境的要求
    2、对测试数据有要求

复杂度分析种类

时间复杂度
空间复杂度

大O表示法

什么是大O表示法

算法的执行效率,粗略地讲,就是算法代码执行的时间。大O时间复杂度实际上并不具体表示代码真正的执行
时间,而是表示代码执行时间随数据规模增长的变化趋势,所以,也叫作渐进时间复杂度(asymptotic timecomplexity),简称时间复杂度。
T(n) = O(f(n))
T(n):代码执行的总时间
n:数据的规模
f(n): 每行代码执行的次数总和

O: 代表执行时间T(n)与f(n)成正比

时间复杂度方法

  • 1.只关注循环执行次数最多的一段代码。

      首先,大O表示法只是表示一个变化趋势,所以我们常常会忽略掉公式中的常量、低阶、系数,只需要记录一个最大的量级,因为常量这些其实对复杂度的影响并不到甚至有些可以忽略不计。
    
  • 2.加法法则:总复杂度等于量级最大的那段代码的复杂度

      总的时间复杂度就等于量级最大的那段代码的时间复杂度。
      funtion fn1 () {
      // 时间复杂度为O(1)
          for(var i =0; i<=100;i++) {
              return i
          }
      // 时间复杂度为O(n)
          for(j =0; j <= n; j++) {
              retrun  j
          }
      // 时间复杂度为O(n²) 
          for(k =0;k <=n;k++){
              for(q =0; q<=n;q++) {
                  return q + k
              }
          }
      }
      由1得出的结论,只关注循环最多的那次,所以他的总复杂度也就是量级最大的复杂度
    
  • 3.乘法法则:嵌套代码的复杂度等于嵌套内外代码复杂度的乘积

       这种情况一般表示于嵌套调用:
       function fn1 () {
           let sum = 0
           for( var i = 0; i<=n; i++ ) {
               sum = i + fn2(i)
           }
       }
       function fn2 () {
          for( var i = 0; i<=n; i++ ) {
             sum = i + fn2(i)
          }
       }
    

常见的时间复杂度

  • O(1)

O(1)只是常量级时间复杂度的一种表示方法,并不是指只执行了一行代码,只要代码的执行时间不随n的增大而增长,这样代 码的时间复杂度我们都记作O(1)。换句话讲,只要在代码中不存在说有循环、递归语句,无论代码有多长,时间复杂度都是O(1)

  • O(n)

  • O(logn)

  • O(nlogn)

  • O(2的n次方)

  • O(n!)

  • O(n+m) O(n* m)

这种时间复杂度和前面的不一样,这个是由两个不同的数据规模来决定的。 function fn1() { for(var i = 0;i<n;i++ ) { return i } for(var j= 0;j<m;j++) { return j } } 由于n和m都是无法确定的数据,所以他的时间复杂度为O(n+m)

空间复杂度

时间复杂度与空间复杂度类似,时间复杂度是为了看时间随着数据变化的增长趋势,那么空间复杂度是为了看存储空间随着数据的变化的一个变化趋势。原理与时间复杂度一致。