常见的时间复杂度量级有:常数阶O(1),对数阶O(logn),线性阶O(n),线性对数阶O(nlogn),平方阶O(n2),立方阶O(n3),K次方阶O(nk),指数阶O(2n)。他们的时间复杂度越来越大,执行的效率越来越低。
下面选取一些较为常用的来讲解一下。
常数阶O(1)
for(int i = 1; i <= 100; i++)
sum += i;
代码执行次数是一个常数,不随n的变化而变化,那这个代码的时间复杂度就都是O(1),如下的代码中虽然含有for循环,但循环次数是100次,不随问题规模变化而变化,因此是常数级O(1)的时间复杂度:
线性阶O(n)
for(int i = 1; i <= n; i++)
sum += i;
这段代码,for循环里面的代码会执行n遍,因此它消耗的时间是随着n的变化而变化的,因此这类代码都可以用O(n)来表示它的时间复杂度。
对数阶O(logn)
同样是for循环,但这段代码的时间复杂度是O(logn),因此不能单纯认为for循环就一定是O(n)的。
for(int i = 1; i <= n; i *= 2)cnt++;
在这个for循环里,i 开始是1,然后不是自增1,而是自乘2,因此i的值依次是1、2、4、8......2x ,也就是当2的x次方大于n时,跳出循环,因此x =ogn, 程序执行了logn次,时间复杂度为:O(logn)
线性对数阶O(nlogn)
线性对数阶O(nlogn) 其实非常容易理解,将时间复杂度为O(logn) 的代码循环n遍的话,那么它的时间复杂度就是 n×O(logn)。
就拿上面的代码加一点修改来举例:
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j *= 2)
cnt++;
平方阶O(n2)
平方阶O(n2)就更容易理解了,如果把O(n)的代码再嵌套循环一遍,它的时间复杂度就是O(n2) 了。
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
cnt++;
其实冒泡排序的时间复杂度也是O(n^2^),以下代码中,当i=1时,执行n-1次,i=2时,执行n-2次......因此总的执行次数也就是 (n-1)+(n-2)...+2+1就是n*(n-1)/2,显然n2的量级更大,因此常数项和n/2可以忽略,时间复杂度即为O(n2):
for(int i =1; i<=n; i++)
for(int j=1; j<=n-i; j++)
if(a[j] > a[j+1])
swap(a[j], a[j+1]);
阶乘 O(n!)
比如用枚举的方法求1~n的全排列,时间复杂度是 O(n!),效率很低。