1、时间复杂度
1.1基本介绍
- 一般情况下,算法中的基本操作语句的重复执行次数时问题规模n的某个函数,用T(n)表示,若是某个辅助函数f(n),使得当n趋近于无穷大时,T(n)/f(n)的极限值为不等于零的常数,则称f(n)是T(n)的同数量级函数,记作T(n)=O(f(n))为算法的渐进时间复杂度,简称时间复杂度。
- T(n)不同,但时间复杂度可能相同。
例如:T(n)=n2+7n+6 与 T(n)=3n2+2n+2他们的T(n)不同,但时间复杂度相同,都是O(n2) - 计算时间复杂度的方法:
- 用常数1替代运行时间中所有加法常数。T(n)=3n2+2n+2 => T(n)=3n2+2n+1
- 修改后的运行次数函数中,只保留最高阶项。T(n)=3n2+2n+1 => T(n)=3n2
- 去掉最高阶的系数。T(n)=3n2 => T(n)=n2 =O(n2)
1.2 常见的时间复杂度
1. 常数阶 O(1)
无论代码执行了多少行,只要没有循环等复杂结构,这个代码的时间复杂度就都是O(1)。
int i=1;
int j=2;
int m=i+j;
2. 对数阶 O(log2n)
O(log2n)的这个2是根据代码变化的。如果i=i*3;
,则是O(log3n)。
提示:如果N = ax(a>0,a ≠1),即a的x次方等于N(a>0,且a≠1),那么数x叫做以a为底N的对数(logarithm),记作x = logaN。其中,a叫做对数的底数,N叫做真数,x叫做"以a为底N的对数。
int i=1;
while(i<n){
i=i*2;
}
3. 线性阶 O(n)
for里面的代码会执行n遍,因此它消耗的时间是随着n的变化而变化的,因此这类代码都可以用O(n)来表示它的时间复杂度。
for(int i=1;i<=n;i++){
j=i;
j++;
}
4. 线性对数阶O(nlog2n)
线性对数阶O(nlog2n)其实非常容易理解,将时间复杂度为O(log2n)的代码循环N遍的话,那么它的时间复杂度就是n *O(log2n),也就是了O(nlog2n)。
for(int m=1;m<n;m++){
i=1;
while(i<n){
i=i*2;
}
}
5. 平方阶 O(n2)
就是嵌套了2层n循环。
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
sum=i+j;
}
}
6. 立方阶 O(n3)
就是嵌套了3层n循环。
7. K次方阶 O(nk)
就是嵌套了k层n循环。
8. 指数阶 O(2n)
常见的算法时间度由小到大依次为:
O(1) < O(log2n) < O(n) < O(nlog2n) < O(n2) < O(n3) < O(nk) < O(2n) 随着问题规模n的不断变大,上述时间复杂度不断增大,算法的执行效率越低。
1.3 平均时间复杂度和最坏时间复杂度
- 平均时间复杂度是指所有可能的输入实例均以等概率出现的情况下,该算法的运行时间。
- 最坏情况下的时间复杂度称最坏时间复杂度。—般讨论的时间复杂度均是最坏情况下的时间复杂度。这样做的原因是:最坏情况下的时间复杂度是算法在任何输入实例上运行时间的界限,这就保证了算法的运行时间不会比最坏情况更长。
- 平均时间复杂度与最坏时间复杂度是否一致,和算法有关。
2、空间复杂度(不详细讨论)
2.1 基本介绍
- 类似于时间复杂度的讨论,一个算法的空间复杂度(space Complexity)定义为该算法所耗费的存储空间,它也是问题规模n的函数。
- 空间复杂度(space Complexity)是对一个算法在运行过程中临时占用存储空间大小的量度。
- 在做算法分析时,主要讨论的是时间复杂度。从用户使用体验上看,更看重的程序执行的速度。一些缓存产品和算法本质上就是用空间换时间。