算法复杂度分为时间复杂度和空间复杂度。
时间复杂度是指执行算法所需要的计算工作量;
而空间复杂度是指执行这个算法所需要的内存空间。
(算法的复杂性体现在运行该算法时的计算机所需资源的多少上,计算机资源最重要的是时间和空间(即寄存器)资源,因此复杂度分为时间和空间复杂度)。
简单来说,时间复杂度指的是语句执行次数,空间复杂度指的是算法所占的存储空间
时间复杂度
计算时间复杂度的方法:
⑴ 找出算法中的基本语句;
算法中执行次数最多的那条语句就是基本语句,通常是最内层循环的循环体。
⑵ 计算基本语句的执行次数的数量级;
只需计算基本语句执行次数的数量级,这就意味着只要保证基本语句执行次数的函数 中的最高次幂正确即可,可以忽略所有低次幂和最高次幂的系数。这样能够简化算法 分析,并且使注意力集中在最重要的一点上:增长率。
⑶ 用大Ο记号表示算法的时间性能。
将基本语句执行次数的数量级放入大Ο记号中。
如果算法中包含嵌套的循环,则基本语句通常是最内层的循环体,如果算法中包含并列的循环,则将并列循环的时间复杂度相加。
按数量级递增排列,常见的时间复杂度有:
常数阶O(1),对数阶O(logn),线性阶O(n),
线性对数阶O(nlogn),平方阶O(n^2),立方阶O(n^3),…,
k次方阶O(n^k),指数阶O(2^n)。
随着问题规模n的不断增大,上述时间复杂度不断增大,算法的执行效率越低。
while(i<n){
i*=2
}
这个复杂度logn
如何判断一个函数是对数级的复杂度?(n经过几次除以a的操作后等于b?)
递归的时间复杂度:
1、如果递归中只进行了一次递归调用,递归深度(进行了多少次递归)为depth,每个递归函数复杂度为T,总体时间复杂度是T*depth,如
function pow(a,b){
if(b==0)return 1;
t=pow(a,b/2);
return t*t
}//T=O(1),depth=O(logn)(b一直除以2直到等于0),整体复杂度logn
2、如果递归中进行了多次递归调用,计算调用的次数(可以画一棵树来解决)。
function f(n){
if(n==0)return 1;
return f(n-1)+f(n-1);
}//这个算法调用次数为2^0+2^1+2^2+……+2^n=2^n+1 - 1,复杂度为2^n
空间复杂度,是对一个算法在运行过程中临时占用存储空间大小的量度。所以它强调的是使用的辅助空间的的大小,而不是指所有的数据所占用的空间。比如开辟一个辅助数组,O(N);开一个二维数组就是O(N2)。如果只用到常量存储数据就是O(1)
要注意的是递归算法的空间复杂度,假如递归深度为N*每次递归的辅助空间大小,如果每次递归的辅助空间为常数,则空间复杂度为O(N)。