常见的时间复杂度量级包括:
常数阶O(1)
线性阶O(n)
平方阶O(n²)
对数阶O(logn)
线性对数阶O(nlogn)
它们的关系:
需要牢记的算法复杂度速记表:
一些时间复杂度计算题摘录:
1
已知一个数组a的长度为n,求问下面这段代码的时间复杂度:
for (i=0,length=1;i<n-1;i++){
for (j = i+1;j<n && a[j-1]<=a[j];j++){ //a[j-1]<=a[j]有序
if(length<j-i+1)
length=j-i+1;
}
}
实际上是求a中有序子数组中最长的长度。譬如,在[1, 8, 1, 2, 5, 0, 11, 9]中,最长的是[1, 2, 5],长度为3 。其时间复杂度与a中元素的实际取值状态相关。 1)若a的所有元素是按照降序方式排列。则外层循环n-1次,每次内层只执行一次,整个开销为θ(n) 2)若a的所有元素是按照升序方式排列。则外层循环n-1次,每次内层需要执行n-i-1次,整个开销为θ(n^2)
所以,一般来说,时间复杂度是Ω(n)的,也是O(n^2)
2
求以下算法的时间复杂度:
void fun(){
int i = 1 ;
while(i <= n){
i = i*2 ;
}
}
分析:设循环执行次数为t,则 2 t ≤ n 2^t \leq n 2t≤n 即 t ≤ l o g 2 n t \leq log_2n t≤log2n
因此时间复杂度为 : O ( log 2 n ) O(\log_2n) O(log2n)
3
求整数n(n>=0)的阶乘的算法如下,求时间复杂度
int fact(int n){
if(n<=1) return 1;
return n*fact(n-1);
}
分析:共执行n次乘法操作,故时间复杂度为O(n)
4
求算法时间复杂度:
int fun(int n){
int i = 0;
int sum = 0;
while(sum < n) sum += ++i;
return i;
}
分析:进行t次循环后,sum = (k+1)*k/2
(k+1)*k/2 < n则时间复杂度为O(
n
1
/
2
n^{1/2}
n1/2)
5
下列语句(1)在最坏的情况下的执行时间复杂度为多少?
for(int i = n-1 ; i > 1 ; i++)
for(int j = 1 ; j <i ;j++){
if(A[j] > A[j+1]){
//..
//交换A[j]与A[j+1] (1)
//..
}
}
分析:
当所有相邻元素为逆序时为最坏情况,该语句执行次数为:
∑
i
=
2
n
−
1
i
−
1
=
(
n
−
1
)
(
n
−
2
)
/
2
\sum_{i=2}^{n-1} {i-1}=(n-1)(n-2)/2
i=2∑n−1i−1=(n−1)(n−2)/2
故时间复杂度为:
O
(
n
2
)
O(n^2)
O(n2)
6
求两个n阶方阵C=A*B的乘积其算法如下:
//右边列为语句执行的频度
void MatrixMultiply(int A[n][n],int B [n][n],int C[n][n])
{
for(int i=0; i <n; i++) //n+1
{
for (j=0;j < n; j++) //n*(n+1)
{
C[i][j]=0; //n^2
for (k=0; k<n; k++) //n^2*(n+1)
{
C[i][j]=C[i][j]+A[i][k]*B[k][j]; //n^3
}
}
}
}
则该算法所有语句的频度之和为:
T ( n ) = 2 n 3 + 3 n 2 + 2 n + 1 T(n) = 2n^3+3n^2+2n+1 T(n)=2n3+3n2+2n+1; 利用大O表示法,时间复杂度为 O ( n 3 ) O(n^3) O(n3)
7
求幂运算,要求时间复杂度小于O(n)
采用递归算法:
//递归深度:logn
//时间复杂度:O(logn)
double pow( double x, int n){
if (n == 0) return 1.0;
double t = pow(x,n/2);
if (n %2) return x*t*t;
return t * t;
}
易知时间复杂度为O(log n)
8
计算下面递归程序的时间复杂度
// O(2^n) 指数级别的数量级,后续动态规划的优化点
int f(int 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
= O(2^n)
9
待更新。。。