视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
通过js示例讲解时间复杂度与空间复杂度
2020-11-27 21:52:53 责编:小采
文档


上边的例子已经说了一个了两层循环的那种,在举一个时间复杂度多块代码的情况时间复杂度的计算方式

function go(i) {
 var sum = 0;
 for (var j = 0; j < i; j++) {
 sum += i;
 }
 return sum;
}
function main(n) {
 var res = 0;
 for (var i = 0; i < n; i++) {
 res = res + go(i); // 这里是重点
 }
}

在上边的代码种第二段代码里边调用了第一段代码,所以说在这个代码里边是

go:(1+n)

在main函数里边的时候是(1+n*go)=(1+n+n*n)

所以最后的时间复杂度是T(n) = O(n²)

3.3 多块代码的时间复杂度

上边距离说明的T(n) = O(n²) ,是一个函数在另一个函数里边被调用,这种情况是被把两个函数的时间复杂度相乘。

还有另外一种情况,就是说在一个函数里边有多块代码,但是并没有被相互调用,那么这种情况的时候,我们只需要取复杂度最大的代码块就可以了

比如说

 function go(n) {

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


 for (var i = 0; i < n; i++) {
 console.log(2)
 }
 }

上边这块代码中,第一块代码有两层循环,通过上边的例子我们已经得知复杂度是

下边这块代码,是n

那么在这种情况的时候,当N接近无限大的时候N是对n²起不到决定性作用的,所以上边这块代码的时间复杂度就是取最大值的n²

3.4 对数阶和相加情况

var i = 1;
while (i <= n) {
 i = i * 10;
}

在这段代码中,可以看到while里边,作为判断条件的i被每次*10,那么所以说最后循环的次数并不是n次,而是说十分之一n次,所以说这个时候的时间复杂度是10i=n,
i=logn

所以得出结论就是时间复杂度是T(n)=O(logn)

然后还有一种情况就是通过改变的变量去增加循环次数的,同理是增加了时间复杂度

还有一些其他的情况比如时间复杂度相加

function go(m,n) {

 for (var i = 0; i < n; i++) {
 console.log(1)
 }

 for (var i = 0; i < m; i++) {
 console.log(2)
 }

}

请看上边这一段,这段代码里边一个函数里边有两个循环,但是形参有两个,我们现在无法得知n和m到底谁大谁小,所以说这个时候代码的时间复杂度是O(m+n)

4. 空间复杂度

4.1 空间复杂度的定义

上边说了那么一大堆的时间复杂度,相比各位已经比较了解了,就名字来看,时间复杂度看的是代码的执行时间的趋势,那么同理的,空间复杂度就是指的占用内存的趋势

4.2 常见的空间复杂度

空间复杂度没有时间复杂度那么复杂,常见的就那么几种

毕竟我感觉不会有人一直循环着各种花样的声明变量吧。。

如果有,那么请打死。。

  • O(1)
  • let a = 1;
    let b = 1;
    let c = 1;
    let d = 1;

    很简单,O(1)

  • O(n)
  • let arr =Array(n)

    看这句代码,代码中创建了一个n长度的数组,很明显数组的长度根据n来决定,所以说
    O(n)

    这里需要说明一下,这里没有用循环,是因为只要不是在循环里边不停的声明变量,只改变值的话是不会层架空间复杂度的

  • O(n²)
  • let arr=[]
    for (var i = 0; i < n; i++) {
     arr[i]=i
     for (var j = 0; j < n; j++) {
     arr[i][j]=j
     }
    }

    怎么样,猛的一看这个代码是不是很刺激,我觉得如果有这种情况的话,一般都会被乱棍打死了。。

    复杂度的优化

    再说优化之前我先盗一张图给大家看一下各个复杂度的曲线图,方便大家有一个直观的认识

    举个比较简单的优化的例子

    console.time('a')
    function go(n) {
     var item = 0;
     for (var i = 1; i <= n; i++) {
     item += i;
     }
     return item;
    }
    console.timeEnd('a')
    
    console.time('b')
    function go2(n) {
     var item = n*(n+1)/2
     return item;
    }
    console.timeEnd('b')
    
    go(1000)
    go2(1000)

    大家可以打印一下看一下

    希望大家原谅我数学不好,记得之前看到过一个等差数列的例子,想不到其他的性能优化的例子

    希望大家看完之后可以了解这些概念,有的时候这个东西真的很重要,找一个曲线比较高的例子

    斐波那契,就是从第三项开始依次等于前两项的和

    斐波那契定义

    function Fibonacci(n) {
     if (n <= 1 ) {
     return n;
     } else {
     return Fibonacci(n - 1) + Fibonacci(n - 2);
     }
    }
    
    console.time('b')
    Fibonacci(????)
    console.timeEnd('b')

    有兴趣的可以试试打印一下,看看时间,不过大概50次的时候你得浏览器就应该没有响应了,具体请往上看曲线图。。

    以上是我对时间复杂度和空间复杂度的一些认识,有不足或者不对的地方,希望指出来

    总结

    下载本文
    显示全文
    专题