时间复杂度是我们衡量和筛选算法的一个常用考量维度,如何理解并使用它,是我们日常工作学习中常常会用到的,但是只要一段时间不用它是会很快被忘记的。所以这里把时间复杂度的概念简要记录一下,方便使用的时候能够快速恢复记忆。
对于算法的衡量一般是从两个维度进行的,一是空间维度,即算法执行所需要占据的内存空间;一是时间维度,即算法执行所需要的时间。时间与空间往往不能兼得,我们很难设计一个既使用很小的空间又能迅速执行的算法,所以在面临时间与空间的选择时,我们往往会选择更加宝贵的时间,毕竟一根内存条还是有价的。
大O符号表示法
对于时间复杂度的衡量,我们最常见的就是使用大O符号表示法,例如
大O符号表示法的完整格式是
在
大O符号表示法从来都不是一个精确的表示法,不要用它来做精确的计算。
常见时间复杂度量级
一般在代码设计中常常出现的时间复杂度量级主要有以下这些:
- 常数阶
。 - 对数阶
。 - 线性阶
。 - 线性对数阶
。 - 平方阶
。 - 立方阶
。 - K方阶
。 - 指数阶
。 - 组合阶
。
以上这些复杂度量级从上到下所表示的复杂度越来越大,执行效率也越来越低。下面就一些示例来说明不同形式的代码其时间复杂度的量级。
常数阶
代码中没有循环结构,无论执行多少行,代码所消耗的时间始终固定,不随着某个变量的操作发生变化,其复杂度就是
|
|
线性阶
代码中只有一层循环结构,没有任何嵌套的循环结构,代码执行所消耗的时间只与循环控制变量线性相关,那么这段代码的复杂度就是
|
|
在线性阶
对数阶
代码中同样只有一层循环结构,没有任何嵌套的循环结构,但是代码执行所消耗的时间与循环控制变量指数相关,那么这段代码的复杂度就是
|
|
在这段代码中,循环不是线性的,循环在
线性对数阶
线性对数阶量级中就已经开始出现多层的循环结构了,在复杂度为
|
|
在这种嵌套的循环结构中,其复杂度的计算方法是各层的复杂度相乘,即:
K方阶
从线性对数阶量级中可以看出,多层循环在进行嵌套的时候,算法复杂度也是逐步相乘的,所以
|
|
在这个示例中使用了一个三层的循环,所以这段代码的复杂度就应该是
但一段代码使用了K方阶量级的复杂度以后,一般就说明这段代码需要进行优化了,并且K方阶的代码在一般情况下总可以找到低复杂度的优化实现。但我们一般所常用的排序算法大多是