时间复杂度
大O复杂度表示法:
int sum(int n){
int s=0; //t: 一行代码一个执行单位
int i=1; //t
for(;i<=n;i++){ //t*n
s=s+i; //t*n
}
return s; //t
}
这段代码的总时间就是t+t+nt+nt+t=2n*t+3t
即执行时间T(n)与执行次数成正比
T(n)=O(f(n))
T(n): 代码执行时间
n:数据规模
f(n):每行代码执行次数总和
O:代码的执行时间与f(n)表达式成正比
上面的方法为 T(n)=O(2n+3)
当n无限大时,低阶、常量、系统都可以忽略
即T(n)=O(n)
int sum(int n){
int s=0;
int i=1;
int j=1;
for(;i<=n;i++){// n
j=1;
for(;j<=n;j++){ //n*n
s=s+i+j; //n*n
}
}
return s;
}
上面的例子T(n)=O(n²)
如何计算时间复杂度:
总复杂度=量级最大的复杂度
int sum(int n){
int s=0;
int i=1;
int j=1;
for(;i<=n;i++){ //t*n
s=s+i; //t*n
}
//这一段嵌套循环的复杂度量级更高
for(;i<=n;i++){// n
j=1;
for(;j<=n;j++){ //n*n
s=s+i+j; //n*n
}
}
return s;
}
T(n)=O(n²)
嵌套代码的复杂度等于嵌套内外代码复杂度的乘积
常见的时间复杂度
- O(1):常量级
不是只执行了一行代码,只要代码的执行不随着数据规模(n)的增加而增加 - O(logn)
T(n)=O(logn)
i = 1;
while(i <= n){
i=i*2;
}
-
O(n)
普通的循环遍历等 -
O(m+n)
int sum(int m,int n){
int s1=0;
int s2=0;
int i=1;
int j=1;
for(;i<=m;i++){
s1=s1+i;
}
for(;j<=n;j++){
s2=s2+j;
}
return s1+s2;
}
空间复杂度
表示算法的存储空间与数据规模之间的增长关系
比如将一个数组拷贝到另一个数组中,就是相当于空间扩大了一倍:T(n)=O(2n),忽略系数。即为:O(n),这是一个非常常见的空间复杂度,比如跳跃表、hashmap的扩容
跳跃表是一种典型的空间换时间