美文网首页
复杂度分析笔记

复杂度分析笔记

作者: 南场41号 | 来源:发表于2020-04-05 08:44 被阅读0次

    常见复杂度

    • O(1) :常数复杂度
    • O(\log\ n):对数复杂度
    • O(n):线性时间复杂度
    • O(n\log\ n):线性对数复杂度
    • O(n^2):平方阶
    • O(n^3):立方
    • O(n^k):K次方阶
    • O(2^n):指数阶
    • O(n!):阶乘

    注意:一般只看最高阶复杂度的运算

    如何计算复杂度

    var n = 1000
    console.log("n=",n)
    
    var n = 1000
    console.log("1、n=",n)
    console.log("2、n=",2*n)
    console.log("3、n=",3*n)
    

    时间复杂度为O(1)

    var sum = 0
    for(var i=1;i<=n;i++){
        sum = sum + i
    }
    

    时间复杂度为O(n)

    for(var i=1;i<=n;i++){
      for(var j=1;j<=n;j++){
            console.log(`i=${i},j=${j}`)
      }
    }
    

    时间复杂度为O(n^2)

    for(var i=1;i<=n;i = i*2){
        console.log('i=',i)
    }
    

    时间复杂度为O(\log\ n )

    变量 i 的值从 1 开始取,每循环一次就乘以 2。当大于等于 n 时,循环结束。

    实际上,变量 i 的取值就是一个等比数列。如果我把它一个一个列出来,就应该是这个样子的
    2^0 \quad 2^1 \quad 2^2\quad \cdots\quad2^k\quad \cdots\quad2^x \ =\ n
    只要知道 x 值是多少,就知道这行代码执行的次数。通过 2^x\ =\ n 求解得\ x\ =\ \log_2n

    所以这段代码的时间复杂度就是 O(log_2n)

    实际上,不管是以 2 为底、以 3 为底,还是以 10 为底,我们可以把所有对数阶的时间复杂度都记为 O(\log n)

    因为对数之间是可以互相转换的,\log_3n 就等于 \log_32 * \log_2n,所以 O(\log_3n) = O(C * \log_2n),其中 C=\log_32 是一个常量。在采用大 O 标记复杂度的时候,可以忽略系数,即 O(Cf(n)) = O(f(n))

    记为O(\log\ n)

    function fibonaccii(n) {
       if (n < 2) {
          return n
       }
       return fibonaccii(n - 2) + fibonaccii(n - 1);
     }
    
    image

    时间复杂度为O(2^n)

    image

    图中可以看出,较优的时间复杂度是O(\log\ n)O(1)O(n\log\ n)以上的都不可取

    🌰1+2+3+\cdots +n累加求和
    //循环累加法
    var sum = 0
    for(var i=1;i<=n;i++){
        sum = sum + i
    }
    

    时间复杂度为O(n)

    //等差数列求和
    var sum = n(n+1)/2
    

    注意:时间复杂度不是O(n^2)而是O(1)

    空间复杂度

    1、数组的长度,有数组就看数组长度,一维O(n),二维(O(n^2)

    2、递归的深度,递归深度O(n)

    总结

    1、常见时间复杂度有O(1)O(\log\ n)O(n)O(n\log\ n),只看最高阶,忽略常数项;

    2、常见空间复杂度有O(n),数组长度、递归深度;

    3、递归的时间复杂度可以用递归状态树来计算,空间复杂度看深度。

    相关文章

      网友评论

          本文标题:复杂度分析笔记

          本文链接:https://www.haomeiwen.com/subject/gjeyphtx.html