算法是指用来操作数据、解决程序问题的一组方法。对于同一个问题,使用不同的算法,也许最终得到的结果是一样的,但在过程中消耗的资源和时间却会有很大的区别。
那么我们应该如何去衡量不同算法之间的优劣呢?
主要还是从算法所占用的「时间」和「空间」两个维度去考量。
- 时间维度:是指执行当前算法所消耗的时间,通常用「时间复杂度」来描述。
- 空间维度:是指执行当前算法需要占用多少内存空间,通常用「空间复杂度」来描述。
接下来主要介绍时间复杂度和空间复杂度的计算方法。
一、时间复杂度
O 时间复杂度并不具体表示代码真正的执行时间,而是表示代码执行时间随数据规模增长的变化趋势,当n变得越来越大时,公式中的低阶,常量,系数三部分影响不了其增长趋势,所以可以直接忽略他们,只记录一个最大的量级就可以了。以下介绍几种常见的时间复杂度量级。
1.常数阶 O(1)
O(1)不是说代码只有一行,这个1它代表的是一个常量,即使它有一万行这样的也是O(1),因为它是固定的不会变化(也就是常量),所以凡是常量级复杂度代码,均记为O(1)
2.线性阶 O(n)
一般一个循环的时间复杂度为O(n):for循环里面的代码会执行n遍,因此它消耗的时间是随着n的变化而变化的,因此这类代码都可以用O(n)来表示它的时间复杂度。
3.平方阶 O(n*n)
一般循环嵌套(即一个for循环里面还有一个for循环)的时间复杂度为O(n*n)
4.O(log n)、O(n*log n)
一般一个循环中循环变量是以倍数(如 i = i *2)变化的,时间复杂度为O(log n):因为这个循环只循环 log n 次。
O(n*log n)一般是复杂度为O(log n)的循环嵌套一个复杂度为O(n)的循环。
注:以上时间复杂度大小为 1 < log n < n < n*log n < n*n 。 对于一个具体算法来说,时间复杂度越小越好。
二、空间复杂度
时间复杂度不是用来计算程序具体耗时的,空间复杂度也不是用来计算程序实际占用的空间的。
空间复杂度是对一个算法在运行过程中临时占用存储空间大小的一个量度,同样反映的是一个趋势。
空间复杂度比较常用的有:O(1)、O(n)、O(n²)
1. O(1)
如果算法执行所需要的临时空间不随着某个变量n的大小而变化,即此算法空间复杂度为一个常量,可表示为 O(1)
2.O(n)
一般算法需要创建大小为n的数组时的空间复杂度为O(n)
注:如今硬件条件已经很好,所以现在算法一般只考虑时间复杂度。
以上为常见的时间和空间复杂度分析,另外还有最好、最坏和平均时间复杂度。此外,递归算法(算法中出现自己调用自己的成分)的时间复杂度、空间复杂度不同于上述。