当前位置:   article > 正文

时间复杂度和空间复杂度,一看就懂,面试前必过一遍

时间复杂度 空间复杂度的计算

转自:公众号【嵌入式linux】

作者:发哥

一、定义

时间和空间是程序的一个硬性指标,一个用来衡量 代码执行的速度 ,一个用来衡量 存储空间的大小

程序 =  数据结构 + 算法

  • 时间复杂度:就是执行程序的快慢,速度越快,时间复杂度就越好。

  • 空间复杂度:就是执行程序需要的存储空间的大小,执行程序需要的存储空间越小就越好。

二、时间复杂度的计算

表示方法

我们一般用 大O符号表示法来表示时间复杂度:T(n) = O(f(n)) n是影响复杂度变化的因子,f(n)是复杂度具体的算法。

常见的时间复杂度量级

  • 常数阶O(1)

  • 线性阶O(n)

  • 对数阶O(logN)

  • 线性对数阶O(nlogN)

  • 平方阶O(n²)

  • 立方阶O(n³)

  • K次方阶O(n^k)

  • 指数阶(2^n)

接下来再看一下不同的复杂度所对应的算法类型。

常数阶O(1)

  1. int a = 1;
  2. int b = 2;
  3. int c = 3;
  4. 123

我们假定每执行一行代码所需要消耗的时间为1个时间单位,那么以上3行代码就消耗了3个时间单位。那是不是这段代码的时间复杂度表示为O(n)呢 ?其实不是的,因为大O符号表示法并不是用于来真实代表算法的执行时间的,它是用来表示代码执行时间的增长变化趋势的。上面的算法并没有随着某个变量的增长而增长,那么无论这类代码有多长,即使有几万几十万行,都可以用O(1)来表示它的时间复杂度。

线性阶O(n)

  1. for(i = 1; i <= n; i++) {
  2.    j = i;
  3.    j++;
  4. }
  5. 1234

看这段代码会执行多少次呢?第1行会执行1次,第2行和第3行会分别执行n次,总的执行时间也就是 2n + 1 次,那它的时间复杂度表示是 O(2n + 1) 吗?No ! 还是那句话:“大O符号表示法并不是用于来真实代表算法的执行时间的,它是用来表示代码执行时间的增长变化趋势的”。所以它的时间复杂度其实是O(n);

对数阶O(logN)

  1. int i = 1;
  2. while(i < n) {
  3.     i = i * 2;
  4. }
  5. 1234

可以看到每次循环的时候 i 都会乘2,那么总共循环的次数就是log2n,因此这个代码的时间复杂度为O(logn)。这儿有个问题,为什么明明应该是O(log2n),却要写成O(logn)呢?其实这里的底数对于研究程序运行效率不重要,写代码时要考虑的是数据规模n对程序运行效率的影响,常数部分则忽略,同样的,如果不同时间复杂度的倍数关系为常数,那也可以近似认为两者为同一量级的时间复杂度。

线性对数阶O(nlogN)

  1. for(m = 1; m < n; m++) {
  2.     i = 1;
  3.     while(i < n) {
  4.         i = i * 2;
  5.     }
  6. }
  7. 123456

线性对数阶O(nlogN) 其实非常容易理解,将时间复杂度为O(logn)的代码循环N遍的话,那么它的时间复杂度就是 n * O(logN),也就是了O(nlogN)。

平方阶O(n²)

  1. for(x = 1; i <= n; x++){
  2.    for(i = 1; i <= n; i++) {
  3.        j = i;
  4.        j++;
  5.     }
  6. }
  7. 123456

把 O(n) 的代码再嵌套循环一遍,它的时间复杂度就是 O(n²) 了。

立方阶O(n³)、K次方阶O(n^k)

参考上面的O(n²) 去理解就好了,O(n³)相当于三层n循环,其它的类似。

三、空间复杂度计算

空间复杂度 O(1)

如果算法执行所需要的临时空间不随着某个变量n的大小而变化,即此算法空间复杂度为一个常量,可表示为 O(1)。

  1. int i = 1;
  2. int j = 2;
  3. ++i;
  4. j++;
  5. int m = i + j;
  6. 12345

代码中的 i、j、m 所分配的空间都不随着处理数据量变化,因此它的空间复杂度 S(n) = O(1)。

空间复杂度 O(n)

  1. int[] m = new int[n]
  2. for(i = 1; i <= n; ++i) {
  3.    j = i;
  4.    j++;
  5. }
  6. 12345

这段代码中,第一行new了一个数组出来,这个数据占用的大小为n,后面虽然有循环,但没有再分配新的空间,因此,这段代码的空间复杂度主要看第一行即可,即 S(n) = O(n)。

总结

评价一个算法的效率主要是看它的时间复杂度和空间复杂度情况。可能有的开发者接触时间复杂度和空间复杂度的优化不太多(尤其是客户端),但在服务端的应用是比较广泛的,在巨大并发量的情况下,小部分时间复杂度或空间复杂度上的优化都能带来巨大的性能提升,是非常有必要了解的。

更多精彩内容(请点击图片进行阅读)

公众号:AI蜗牛车

保持谦逊、保持自律、保持进步

个人微信

备注:昵称+学校/公司+方向

如果没有备注不拉群!

拉你进AI蜗牛车交流群

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/681058
推荐阅读
相关标签
  

闽ICP备14008679号