对于许多初入算法的萌新来说,做算法最难受的时候就是题目明确要求了时间复杂度为多少,但是自己却不知道怎么算,代码自然也就无从下手,本人也有过这样的感受,然后去找了许多文章,了解了后并将其整理出来了。
关于时间复杂度的计算,基本都遵循着以下三个步骤:
- 找到执行次数最多的语句
- 计算语句执行次数的数量级
- 用 O 来表示结果
常见的时间复杂度按耗费是时间从小到大依次是:
O(1) < O(logn) < O(n*logn) < O(n^2) < O(n^3) < O(2^n) < O(n!) < O(n^n)
计算时间复杂度
关于时间复杂度的计算,下面通过一些例子来给大家说明:
1、常数阶 O(1)
无论代码执行了多少行,只要没有循环这类复杂结构,那它的时间复杂度就都是O(1),如:
let i = 1;
let j = 2;
let m = i + j;
2、线性阶O(n)
for(let i = 0; i < n; i++) {
console.log(i);
}
for循环里面的代码会执行n遍,因此它消耗的时间是随着n变化的,so这类代码的时间复杂度都可以用O(n)表示。
3、对数阶O(logn)
let i = 1;
while(i < n) {
i = i * 2;
}
由这段代码可知,假设我们循环了x次之后,i就大于n了,退出循环,得到公式2^x=n,x=log2n,说明循环log2n次后,这个循环便结束了,因此时间复杂度为O(logn)。
4、线性对数阶O(n*logn)
这个还是挺好理解的,让我们对上一段代码做一些修改
for(let j = 0; j < n; j++) {
let i = 1;
while(i < n) {
i = i * 2;
}
}
5、平方阶O(n^2)
这个的话只要把O(n)的代码在嵌套一层for循环就可以了
for(let i = 0; i < n; i++) {
for(let j = 0; j < n; j++) {
console.log(i, j);
}
}
顺便提一下,如果将其中一个n改为m,则时间复杂度为O(m*n);
6、立方阶O(n^3)
最简单的就是三个for循环嵌套,另外有些其它的,如:
for(let i = 1; i < n; i++) {
for(let j = 1; j <= i; j++) {
for(let k = 1; k <= j; k++) {
//...
}
}
}
上面这段代码循环了(1^2+2^2+3^2+...+n^2)=n(n+1)(2n+1)/6≈(n^3)/3,所以时间复杂度是O(n^3);
剩下的参考上面的去理解就行了,都差不多。
对了,最后再补充一句,平均运行时间是指期望的运行时间,而我们平常所提到的运行时间都是指最坏情况的运行时间。
如有错误或不足之处还请指出,本人也还是一名大三学生,仍在成长中,感谢阅读。