算法(Algorithm)是求解一个问题需要遵循的,被清楚指定的简单指令的集合。
一个算法的评价主要从时间复杂度和空间复杂度来考虑。而时间复杂度是一个函数,定性描述该算法的运行时间,通常用大O符号表示。
常见的时间复杂度有O(1),O(logn),O(n),O(n2),O(2n)…等。
下面就来讲讲时间复杂度是怎么推算出来的吧。
在计算机科学中,时间复杂性,又称时间复杂度,算法的时间复杂度是一个函数,它定性描述该算法的运行时间。这是一个代表算法输入值的字符串的长度的函数。时间复杂度常用
大O符号
表述,不包括这个函数的低阶项
和首项系数
。使用这种方式时,时间复杂度可被称为是渐近
的,亦即考察输入值大小趋近无穷
时的情况。
我们定义算法中的语句执行次数称为语句频度或时间频度为T(n)。即T(n)表示程序的执行次数 。
方法1执行多少次:
public int method1(){
System.out.println("hello"); //执行1次
return 0; //执行1次
}
没错,它内部一共执行2次。
那么我们来看下面的方法2执行几次:
public int method2(int n){
for(int i = 0; i<n ; i++){
//i = 0 执行1次,i
System.out.println("hello"); //输出语句执行n次
}
return 1; //return 执行一次
}
对,它一共执行了 3n+3 次。那么对于方法1就有 T(n) = 2;对于方法2就有 T(n) = 3n + 3。
实际的代码肯定比示例中的代码复杂得多,去统计代码的执行次数显然不可能,所以算法一般使用T(n)的渐进估算值
来反映代码的执行速度。而这个估算值我们用”时间复杂度”来表示。
所以针对方法1和方法2,如何根据T(n)估算出时间复杂度:
总结以上规律:
方法1的时间复杂度为 O(1):
//时间复杂度为 O(1)
public void m1(){
System.out.println("A");
System.out.println("B");
...
System.out.println("L");
}
方法2的时间复杂度为 O(n):
//时间复杂度为 O(n)
public int method2(int n){
for(int i = 0; i < n ; i++){
System.out.println("a");
}
return 1;
}
方法3 时间复杂度为 O(n^2):
//时间复杂度为 O(n^2)
public void method3(int n){
for(int i = 0; i < n ; i++){
for(int j = 0 ; j < i ; j ++){
System.out.println("a");
}
}
}
方法4的时间复杂度为O(logn):
public void method4(int n){
int i = 1;
while(i<n)
{
i = i * 2;
}
}
从上面代码可以看到,在while循环里面,每次都将 i 乘以 2,乘完之后,i 距离 n 就越来越近了。我们试着求解一下,假设循环x次之后,i 就大于 2 了,此时这个循环就退出了,也就是说 2 的 x 次方等于 n,那么 x = log2^n
也就是说当循环 log2^n 次以后,这个代码就结束了。因此这个代码的时间复杂度为:O(logn)
方法5的时间复杂度为O(nlogN) :
public void method5(int n) {
for (int m = 1; m < n; m++) {
int i = 1;
while (i < n) {
i = i * 2;
}
}
}
线性对数阶O(nlogN) 其实非常容易理解,将时间复杂度为O(logn)的代码循环N遍的话,那么它的时间复杂度就是 n * O(logN),也就是了O(nlogN)。
一般常见的时间复杂度进行如下排序(由快到慢)。
再用曲线图看一下时间复杂度。
从图中也可以看出,随着元素变多,指数、阶乘级别的增长是最快的。显而易见其执行效率最低。
我们来举个例子:
算法A的相对时间规模是T(n)= 100n,时间复杂度是O(n)
算法B的相对时间规模是T(n)= 5n2,时间复杂度是O(n2)
算法A运行在老旧电脑上,算法B运行在某台超级计算机上,运行速度是老旧电脑的100倍。
那么,随着输入规模 n 的增长,两种算法谁运行更快呢?
从表格中可以看出,当n的值很小的时候,算法A的运行用时要远大于算法B;当n的值达到1000左右,算法A和算法B的运行时间已经接近;当n的值越来越大,达到十万、百万时,算法A的优势开始显现,算法B则越来越慢,差距越来越明显。
这就是不同时间复杂度带来的差距。
学好算法,则必须要理解时间复杂度这个重要基石。通过以上的分析,相信大家对时间复杂度有了一定的了解,大家共同进步,加油。