算法:
算法(Algorithm)是指用来操作数据、解决程序问题的一组方法。
同一个问题,使用不同的算法,也许最终得到的结果是一样的,但在过程中消耗的资源和时间却会有很大的区别。
我们应该如何去衡量不同算法之间的优劣呢?
主要是从算法所占用的「时间」和「空间」两个维度去考量。
- · 时间维度:是指执行当前算法所消耗的时间,通常用「时间复杂度」来描述。
- · 空间维度:是指执行当前算法需要占用多少内存空间,通常用「空间复杂度」来描述。
时间复杂度:
一个算法中的语句执行次数称为语句频度或「时间频度」。记为T(n)。时间频度T(n)中,n称为问题的规模,当n不断变化时,时间频度T(n)也会不断变化。算法的时间复杂度也就是算法的时间度量,记作:T(n) = O(f(n))。它表示随问题规模n的增大,算法执行时间的增长率和f(n)的增长率相同,称作算法的渐进时间复杂度,简称「时间复杂度」。
常见的时间复杂度量级有:
· 常数阶:O(1)
· 线性阶:O(n)
· 平方阶:O(n^2)
· 立方阶:O(n^3)
· 对数阶:O(logn)
· 线性对数阶:O(nlogn)
· 指数阶:O(2^n)
常见的时间复杂度之间的关系:
所消耗的时间从小到大
O(1) < O(logn) < O(n) < O(nlogn) < O(n^2) < O(n^3) < O(k^n) < O(n!)
空间复杂度:
空间复杂度(SpaceComplexity)是对一个算法在运行过程中临时占用存储空间大小的一个量度,同样反映的是一个趋势,一个算法所需的存储空间用f(n)表示。S(n)=O(f(n)),其中n为问题的规模,S(n)表示空间复杂度。
若算法执行时所需的辅助空间相对于输入数据量而言是个常数,则称此算法为原地工作,空间复杂度为O(1)。当一个算法的空间复杂度与n成线性比例关系时,可表示为O(n),类比时间复杂度。
空间复杂度比较常用的有:O(1)、O(n)、O(n²)
举例说明:
如果算法执行所需要的临时空间不随着某个变量n的大小而变化,即此算法空间复杂度为一个常量,可表示为 O(1)。
int i = 1;
int j = 2;
++i;
j++;
int m = i + j;
代码中的 i、j、m 所分配的空间都不随着处理数据量变化,因此它的空间复杂度 S(n) = O(1)
int[] m = new int[n]
for(i=1; i<=n; ++i)
{
j = i;
j++;
}
这段代码中,第一行new了一个数组出来,这个数据占用的大小为n,这段代码的2-6行,虽然有循环,但没有再分配新的空间,因此,这段代码的空间复杂度主要看第一行即可,即 S(n) = O(n)
最后补一个,我们在学数据结构的时候,最常用的一些时间复杂度和空间复杂度。