时间复杂度 ——简述与分析
目录
## 概念简述:
算法复杂度分为时间复杂度和空间复杂度。时间复杂度是指执行算法所需要的计算工作量,在计算机
科学中,算法的时间复杂度是一个函数,它定性描述了该算法的运行时间,是一个关于代表算法输入值
的字符串的长度的函数。时间复杂度常用大 O 符号表述,如:O(1)、O(n)、O(lgn)、O(n^2)等。不包括这个
函数的低阶项和首项系数。使用这种方式时,时间复杂度可被称为是渐近的,它考察当输入值大小趋近无
穷时的情况。
## 明确:
1. O 描述的是一个算法或操作的渐进时间复杂度,即所耗费时间与输入数据规模间的关系
2. 一般来说,n处于趋近于无穷的情况下
## 举例分析:
简单来说 "O" 描述的是算法的运行时间与输入数据之间的关系,如:
// 求和:O(n),其中定义n为nums中的元素个数
public static int sum (int[] nums) {
int sum = 0;
for(int num : nums)
sum += num;
return sum;
}
忽略常数条件下,此算法运行时间与nums元素个数呈线性关系(n的幂为一次方),即nums中元素个数越
多,将导致算法的运行时间变长
分析:
针对于线性方程 T = c1*n + c2 :
算法中诸如通过遍历nums从中获取元素、将 sum 与 num 进行求和等操作所消耗的总时间视为 c1,
诸如初始化 sum、返回 sum 等操作视为 c2,故此算法实际消耗时间为 c1*n + c2
针对于此算法:
如果我们在分析算法时将 c1 与 c2 具体值也一同分析出来,一方面必要性不大,另一方面有些情况
下也是不可能的,如通过遍历取出 nums 中元素的操作,不同的语言不同的实现实际运行的时间也
是不等的同时也受制于计算机自己的配置与性能,故不可能精确地判断出 c1 与 c2 的数值,这也是
为什么我们在一开始声明忽略常数的原因。
## 理论分析:
经过上述分析,也就是忽略常数的情况下,假如两个算法耗费时间如下:
T = 2 * n + 2
T = 2000 * n + 10000
那么这两个算法在O的意义下都是O(n)线性时间的算法的算法,即消耗的时间与输入数据的规模之间
呈线性关系。
而对算法:
T = 1 * n * n + 0
此算法时间复杂度为O(n^2),即消耗的时间与输入数据的规模之间呈平方关系,也就是说大概率情况
下此算法的性能要低于上方两者
另外针对于算法:
T = 2 * n * n + 300 * n + 10
此算法时间复杂度仍为O(n^2),因为n趋近于无穷,此时低阶项 300*n 将被忽略。
[注意]:
1. 虽然并不代表对于任意输入来说O(n)要优于O(n^2),但是n更准确的含义为渐进时间复杂度,实际上描
述的是当n趋近于无穷的情况,此时O(n)必然是优于O(n^2)的。
2. 通常来说,n越大,一个低阶时间复杂度算法的优势将更容易显现出来
3. 因为或多或少也受常数的影响,有些时候在实际的工程中,也会利用当n较小时高阶算法可能优于低阶
算法的情况。