时间复杂度是什么?
首先,时间复杂度是一个函数,用大O表示,比如O(1)、O(n)、O(logN)…
主要用来定性描述一个算法的运行时间。
先来看下面的图,下面的图中列举了几种常见的时间复杂度:
在上面的图中,我们可以关注下面的几条线:
- 紫色的为1的线
- 以2为底的logN
- 绿色的为n的线
- 红色的为n的2次方的线
我们需要关注上面这几条线的走势,例如 红色的为n的2次方的线明显比绿色的为n的这条线要陡峭,所以红色的线表示的时间复杂度n的2次方大于绿色的线表示的n。
下面来通过代码来理解一下时间复杂度。
例如:
let i = 0;
i += 1;
上面的代码无论何时执行,永远都会执行一次,所以上面的这两行代码可以说他们的时间复杂度为O(1)。
再来看下面的代码,
for(let i = 0; i < n; i ++) {
console.log(i);
}
上面的代码因为开启了一个循环,所以一共会执行n次。所以时间复杂度可以理解为O(n)。
再来看下面的代码:
let i = 0;
i += 1;
for(let j = 0; j < n; j ++) {
console.log(j);
}
可以看到,上面的代码相当于是把之前的两个示例代码结合到一起。
第一段代码的时间复杂度为O(1), 第二段代码的时间复杂度为O(n),那么这两段代码加在一起的时间复杂度为什么呢,是O(n+1)吗?
正确的时间复杂度应该为O(n)。
为什么两段不同的时间复杂度代码加在一起为O(n)呢?
计算时间复杂度的时候,如果两个时间复杂度的代码先后排列,要取时间复杂度更大的那个。
再来看下面的代码:
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
console.log(i, j);
}
}
上面的代码中,嵌套了两层的for循环,那么此时如果要计算整体的时间复杂度,就需要将两个时间复杂度相乘。
第一层的时间复杂度为O(n), 第二层的时间复杂度为O(n),二者相乘也就是: O(n) * O(n) = O(n ^ 2)。
时间复杂度的加法时,需要取较大的那个时间复杂度,忽略增长趋势较小的时间复杂度。时间复杂度为乘法时,就要按照正常的乘法来进行计算。
再来看下面的这一段代码:
let i = 0;
while (i < n) {
console.log(i);
i *= 2;
}
上面的代码实际上相当于在不断的计算2的一次方、2的二次方、2的三次方等等。直到最终结果大于等于 n。
那么while循环当中的代码到底执行了多少次呢?
答案是一共执行了logN次,通过数学中的log函数,可以计算出2的多少次方为N,所以说,此时上面的代码时间复杂度为O(logN)。
补充:
在数学当中,log函数的定义如下:
关于log函数,可以参考 这篇文章。