时间复杂度的计算方法
这里有一段代码:
int fun(int n) {
int sum = 0;
int i = 1;
int j = 1;
for (; i <= n; ++i) {
j = 1;
for (; j <= n; ++j) {
sum = sum + i * j;
}
}
}
2,3,4行代码的执行时间都为1个单位时间,5,6行代码的执行时间为n个单位时间,7,8行代码执行时间为n*n个单位时间,那么T(n)(总执行时间)=3+2n+2n²个单位时间,即T(n) = (3+2n+2n²)×单位时间,T(n)与(3+2n+2n²)成正比,那么我们可以得到一个公式:T(n) = O(f(n)),T(n)即总执行时间,f(n)即3+2n+2n²,O()即表示f(n)与T(n)成正比。当数据规模极其庞大时,可以忽略掉f(n)中的常量和低阶系数,那么T(n) 可以表示为O(n²),即T(n)=O(n²).
几种常见的复杂度阶级:
O(1)常量级复杂度
int i = 8;
int j = 6;
int sum = i + j;
一般情况下,只要算法中不存在循环语句、递归语句,即使有成千上万行的代码,其时间复杂度也是Ο(1)。
O(logn)对数阶复杂度
i=1;
while (i <= n) {
i = i * 2;
}
这个很常见,同时也是最难分析的一种时间复杂度,可以把它看成等比数列 2¹ 2² 2³…2x(x表次方)=n,那么它需要执行x遍才结束,x如何算出呢,通过2的x次方=n,可以知道x=log2n(2为下标),所以,这段代码的 时间复杂度就是O(log2n)。我们知道,对数之间是可以互相转换的,log3n就等于log32 * log2n,所以O(log3n) = O(C * log2n),其中C=log32是一个常量。基于我们前面的一个理论:在采用 大O标记复杂度的时候,可以忽略系数,即O(Cf(n)) = O(f(n))。所以,O(log2n) 就等于O(log3n)。因此,在对数阶时间复杂度的表示方法里,我们忽略对数的“底”, 统一表示为O(logn)。
O(n)、O(m*n)、O(m+n)、O(n²)等都不说了一看代码就知道了的。
又这么晚了,学习的时间总是过得特别快啊,熬夜的后果就是脑袋疼。最好时间复杂度那些就下次再记了。