如何快速掌握大O表示法

如何判断一堆代码是否够简化,是否还有优化空间,除了在代码的写法上的优化外(比如把 if else 写成自己都看不懂的超长三目),另一种方法就是判断时间复杂度空间复杂度,采用一定的方法为代码优化提供理论基础。

(本文是对极客时间学习的总结)

 

日常惯例,先来看一波什么是大O表示法吧; 据百度词条可知:

词条上说了大O表示法大概的概念,注意上述最后一句,当输入量n逐渐增大时,时间复杂度的极限情景称为算法的“渐进时间复杂度”,简单来说如果在输入量n很小,或者输入量n最大值已知的情况下,大O表示法大的并不一定在时间上就运行地慢,所以大O表示法只是一个 “渐进时间复杂度” 的概念,在写代码是可以提供一定的参考价值,并不一定十分准确,很多时间具体情况需要具体分析。

 

既然我们认识了什么是大O表示法,那接下来就先看一看有哪些层级:

直接上图:

 

我们先从第一个说起。

先看一个例子:

let a = 1;
let b = 2;
let c = a + b;

上述代码中每一行都是一个次执行时间,所以以上代码的时间复杂度是O(1+1+1),所以代码的复杂度是O(1)。

大O表示法表示的是代码执行时间随数据规模增长的变化趋势,所以当n无限大时,可以忽略公式中的常量、低阶、系数三部分。

 再看下一段代码

function cal(n){
    let sum = 0;
    for (let i=0; i<n; i++) {
        sum += i;
    }
    return sum
}

代码中第二行只执行了一次所以复杂度是O(1),第三四行代码执行了n次,所以复杂度就是O(n),那么代码总体的复杂度就是O(1+n+n),我们去掉常量和低阶,这段代码的时间复杂度就是O(n)。

再来看

function cal(n){
    let sum = 0;
    let sum1 = 0;
    for (let i=0; i<n; i++) {
        sum += i;
        for (let j = 0; j<n; j++){
            sum1 += j
        }
    }
    return [sum,sum1]
}

代码块中第二三行都是执行一次,复杂度都是O(1),第四五行执行了n次,复杂度是O(n),第六七行,执行了O(n*n)次,就是O(n²),所以以上代码的复杂度就是O(1+1+n+n+n²+n²),去掉常量和低阶,代码的复杂度就是O(n²)。

对于比较复杂的函数,分析方法是同样的。看下面代码

function cal(n){
    let sum = 0;
    let sum1 = 0;
    for (let i=0; i<n; i++) {
        sum += i + f(i);
    }
    return sum
}

function f(n){
    let sum = 0;
    let sum1 = 0;
    for (let i=0; i<n; i++) {
        sum += i;
    }
    return sum
}

代码块中如果不看f(i),cal()函数只是一个普通的函数,第四五行就代表他的时间复杂度O(n),因为f(i),也是一个函数,所以第五行的复杂度不是O(n)而是O(n*n),所以四五行总的复杂度就是O(n+n*n),所以代码总的复杂度就是O(1+1+n+n²),最后得到的就是O(n²)。


上面是几种最常见的复杂度例子,下面我们来看一点不一样的。

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

代码块中只有一个简单的循环,原本其复杂度应该是O(n),但是因为条件从i++改为了i*=2,所以代码中的i的值就是一个等比数列

2º 2¹ 2² 2³ ...2^k...2^x = n,所以我们只需要知道x就知道代码的循环次数了。2^x = n,所以x=,所以时间复杂度就是,我们去掉其中的常数,最后的时间复杂度就是O(logn)。

上面代码的复杂度是O(logn),如果我们按照这个方法将他循环n遍,那么他的复杂度就是O(n*logn),最后得到的结果是O(nlogn),这就是O(nlogn)的由来了。

代码的时间复杂度暂时就总结到这,后续还有最好情况时间复杂度,最坏情况时间复杂度、平均情况时间复杂度和均摊情况时间复杂度。下次更新再总结。


提一嘴

function select(word, arr){ 
    for(let i=0; i<arr.length; i++){
        if(arr[i]==word) return i
    }
}

上面代码块中如果word刚好在数组第一个位置,那么循环在第一次的时候结束的时候就退出了,那么上面代码复杂度就是O(1),如果在数组的第n个位置数组循环了n次,那么复杂度就是O(n),所以这就是最好情况时间复杂度和最坏情况时间复杂度。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值