本文参考文档:https://zhuanlan.zhihu.com/p/50479555
只是用自己理解的语言整理了一下,相当于记个笔记。请点击链接支持原作者哟~
复制代码
算法(Algorithm)是指用来操作数据、解决呈现问题的一组方法。也就是说,能够对一定规范的输入,在有限时间内或得所要求的输出。不同的算法可能用不同的时间、空间或效率来完成同样的任务。所以,一个算法的优劣可以从空间和时间两个维度去进行衡量。
时间维度:是指执行当前算法所消耗的时间,我们通常用「时间复杂度」来描述。
空间维度:是指执行当前算法需要占用多少内存空间,我们通常用「空间复杂度」来描述。
一、时间复杂度
显然,把一个算法程序运行一遍,我们就自然而然知道它所消耗的时间了,但是,这种方式非常容易受运行环境的影响,运行机器的性能高低,测试时使用的数据规模大小等都是影响因素。更何况,我们在写算法的时候,还没有办法去完整的运行。
因此,另一种更为通用的方法就出来了:「大O符号表示法」,即T(n) = O(f(n))
那如何计算时间复杂度呢,看下面这个例子:
for i in range(n): # 1个颗粒时间
j = i # n个颗粒时间
j += 1 # n个颗粒时间
复制代码
假设每行代码的执行时间都是一样的,那么总时间就是:1颗粒时间+n颗粒时间+n颗粒时间=(1+2n)个颗粒时间。即,T(n)=(1+2n)*颗粒时间。可以看出,这个算法的耗时是随着n的变化而变化,而当n无限大的时候,常量1和倍数2也意义不大。因此,我们可以简化的将这个算法的时间复杂度表示为:T(n)=O(n)。
常见的时间复杂度量级有:
常数阶O(1)
对数阶O(logN)
线性阶O(n)
线性对数阶O(nlogN)
平方阶O(n²)
立方阶O(n³)
K次方阶O(n^k)
指数阶(2^n)
上面从上至下依次的时间复杂度越来越大,执行的效率越来越低。
下面选取一些较为常用的来讲解一下:
1、对数阶O(logN)
i = 1
while i
i = i * 2
复制代码
假设循环x次后,i就大于2,此时循环退出,也就是说2的x次方等于n,那么x = log2^N。也就是说当循环log2^N次以后,代码结束。因此上面代码的时间复杂度为O(logN)。
2、线性对数阶O(nlogN)
线性对数阶O(nlogN) 其实非常容易理解,将时间复杂度为O(logn)的代码循环N遍的话,那么它的时间复杂度就是 n * O(logN),也就是了O(nlogN)。
for m in range(n):
i = 1
while i < n:
i = i * 2
复制代码
一、空间复杂度
同时间复杂度,空间复杂度是对一个算法在运行过程中临时占用存储空间大小的一个量度,同样反映的是一个趋势,用S(n)来定义。
而空间复杂度比较常用的有:O(1)、O(n)、O(n²)
1、空间复杂度O(1)
如果算法执行所需要的临时空间不随着某个变量n的大小而变化,即此算法空间复杂度为一个常量,即可表示为O(1)
i = 1
j = 2
i += 1
j += 1
m = i + j
复制代码
代码中的i,j,m所分配的空间都不随着处理数据量变化,因此它的空间复杂度S(n) = O(1)
后续会根据数据结构进行分类,整理python算法面试常考题目,会在每个算法后标明时间复杂度和空间复杂度。欢迎关注并指正~~