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

复杂度分析笔记

作者: 南场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