复杂度分析/大O表示法:
一、渐进时间复杂度(时间复杂度)
1、三种分析法则
1)只关注循环执行次数最多的一段代码
int cal(int n) {
int sum = 0;
int i = 1;
for (; i <= n; ++i) {
sum = sum + i;
}
return sum;
}
以上这段代码2,3行都是常量单位时间,与n无关,与复杂度无关,看4,5行代码都需要执行n次,则整段代码的时间复杂度为O(n)
2)加法法则:总复杂度等于量级最大的那段代码的复杂度
int cal(int n) {
int sum_1 = 0;
int p = 1;
for (; p < 100; ++p) {
sum_1 = sum_1 + p;
}
int sum_2 = 0;
int q = 1;
for (; q < n; ++q) {
sum_2 = sum_2 + q;
}
int sum_3 = 0;
int i = 1;
int j = 1;
for (; i <= n; ++i) {
j = 1;
for (; j <= n; ++j) {
sum_3 = sum_3 + i * j;
}
}
return sum_1 + sum_2 + sum_3;
}
该部分代码中分三部分,第一部分与n无关为常量,第二部分执行n次表示为O(n),第三部分循环嵌套执行n2次表示为O(n2),整段代码复杂度取最大的O(n2),抽象成公式,T1(n)=O(f(n)),T2=O(g(n)),T(n)=max(O(f(n)),O(g(n))),T(n)=O(max(f(n),g(n))),加法还有一种情况就是在有多个数据规模的时候,且数据规模不为常量时,需要叠加
3)乘法法则:嵌套代码的复杂度就是内外复杂度的乘积
T(n)=T1(n)*T2(n),T(n)=O(f(n))*O(g(n))=O(f(n)*g(n)),假设T1(n)=O(n),T2(n)=O(n2),则T(n)=O(n)*O(n2)=O(n3).
1int cal(int n) {
2 int ret = 0;
3 int i = 1;
4 for (; i < n; ++i) {
5 ret = ret + f(i);
6 }
7 }
8
9 int f(int n) {
10 int sum = 0;
11 int i = 1;
12 for (; i < n; ++i) {
13 sum = sum + i;
14 }
15 return sum;
16 }
4,5行代码中嵌套了f方法,12,13执行n次,整段代码的时间复杂度为O(n2)
2、复杂度常见实例
先列举(按复杂度递增):常量阶O(1),对数阶O(logn),线性阶O(n),线性对数阶O(nlogn),平方阶O(n2),立方阶O(n3)
1)常量阶O(1):只要代码执行时间不会随着n增大而增大,则就是常量阶,代码中不存在循环,递归等,无论代码量多少都是常量阶
2)对数阶O(logn),线性对数阶O(nlogn):
二、渐进空间复杂度(空间复杂度)