算法评估标准:时间复杂度与空间复杂度

1 概念

最近开始看看leetcode,发现自己对时间复杂度和空间复杂度没有一个清晰地认识。就去看了看程序员小灰写的算法之旅。这里写篇博客记录一下这部分的知识方便以后查阅。


先说说什么是算法:
在计算机领域里,算法是一系列程序指令,用于处理特定 的运算和逻辑问题。 衡量算法优劣的主要标准是时间复杂度和空间复杂度。


而是什么是时间复杂度和空间复杂度呢?
**时间复杂度:时间复杂度是对一个算法运行时间长短的量度。**用大O表 示,记作T(n)=O(f(n))。
常见的时间复杂度按照从低到高的顺序,包括O(1)、 O(logn)、O(n)、O(nlogn)、O(n2)等。


**空间复杂度:**空间复杂度是对一个算法在运行过程中临时占用存储空间 大小的量度用大O表示,记作S(n)=O(f(n))。
常见的空间复杂度按照从低到高的顺序,包括O(1)、 O(n)、O(n2)等。其中递归算法的空间复杂度和递归深度成正 比。

2 时间复杂度

可以对抽象出计算的时间公式,然后对公式使用一下规则

  • 如果运行时间是常数量级,则用常数1表示
  • 只保留时间函数中的最高阶项
  • 如果最高阶项存在,则省去最高阶项前面的系数



T(n) = 2,只有常数量级,时间复杂度为:T(n) =O(1)。
T(n)= 3n,最高阶项为3n,省去系数3,时间复杂度为:T(n)=O(n)。
T(n) = 5logn, 最高阶项为logn, 时间复杂度为:T(n)=O(logn)
T(n) = 5*n^3+ 3n 最高阶项为3n 省去系数5 时间复杂度是O(n^3)


时间复杂度的是对真正的时间复杂度的一种渐进(大 O 时间复杂度实际上并不具体表示代码真正的执行时间,而是表示代码执行时间随数据规模增长的变化趋势),模拟的是n趋于无穷大时的复杂度。所以才有上面的计算规则,应因为在n趋近于无穷大时,其他因素都可以忽略。

几种常见时间复杂度:
常数时间复杂度:如果对于一个算法,T(n)的上界与输入大小无关,则称其具有常数时间,记作O(1),如访问数组内的单个元素,散列表等。
线性时间复杂度:如果需求是找到无序数组中的最小元素,因为需要遍历所有元素来找到最小值,是一个线性时间操作,记作O(n)
对数时间复杂度:计算机采用二进制计数,所以对数一般以2为底。由于不同的对数公式只有底数不同,而且都是常数,所以O计法中将这个底数抛弃,记为O(logn),常见的有二叉树相关操作和二分搜索。对数时间中每增加一个输入,所需额外计算时间变小。
指数时间复杂度:一个问题求解所需要的计算时间n随着n的增加呈指数型增长
以上几种时间复杂度, 当n的取值足够大时,不难得出下面的结论
O(1)<O(logn)<O(n)<O(n2)

3 空间复杂度

存储算法本身所占的存储空间
算法的输入输出数据所占用的存储空间
算法在运行过程中临时占用的存储空间


基于以上规则也可以总计出来几种常见的空间复杂度
1. 常量空间。当算法的存储空间大小固定,和输入规模没有直接的关系时,空间复杂度记作O(1)。
2 线性空间。当算法分配的空间是一个线性的集合(如数组),并且集合大小和输入规模n成正比时O(n)
3 二维空间。当算法分配的空间是一个二维数组集合,并且集合的长度和宽度都与输入规模n成正比时,空间复杂度记作O(n2)
4 递归空间 执行递归操作所需要的内存空间和递归的深度成正比。纯粹的递归操作的空间复杂度也是线性的,如果递归的深度是n,那么空间复杂度就是O(n)。


总体而言,一个算法的空间复杂度只考虑运行过程中为局部变量分配的存储空间的大小,包括:

  • 参数表中形参变量分配的存储空间
  • 函数体中定义的局部变量分配的存储空间
  • 如果一个算法是递归的,那么空间复杂度是递归所使用的堆栈空间大小,

4 参考链接

漫画算法:小灰的算法之旅
https://zhuanlan.zhihu.com/p/118425860

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章