时间复杂度详解
我们可以使用著名的高斯定理来解释什么是时间复杂度,时间复杂度的重要性
也就是从小到大我们所熟悉的一个定理 1+2+3+4+5+6+….+100的结果
使用高斯定理我们可以很轻松的算出答案
sum = 1 + 2+ 3 + 4 + 5+….+99 + 100
sum = 100 + 99+ 98 +97 +96+….+2 + 1
sum + sum = 101 +101 +101 + 101 + 101 +…… (共100个)
sum = 10100 / 2 = 5050
大家可以看出高斯定理是可以非常迅速的算出答案,我们可以使用程序来计算
我们先用最基础的for循环来计算答案
int sum = 0;
for (int i = 1; i <= 100; i++){
sum = sum + i;
}
System.out.println(sum);
}
由程序可知for循环 循环了 100次才算出答案
当我们使用等差数列中的高斯定理来运算时
int n = 100 ;
int sum = (1 + n)*n/2;
System.out.println(sum);
可以看到我们只运算了一次就可以算出答案而最开始的for循环则需要循环100次才能算出答案
接下来我们就可以对时间复杂度来下一个定义了
- 什么是时间复杂度
- 时间复杂度是算法的时间量度也就是算法的执行时间
- 我们定义算法的总执行次数为 T(n) 进而分析随n的变化来确定 T(n)的次数算法的时间复杂度记作为 T(n) = O(f(n))其中 f(n)是关于n的函数,而n则被称为问题规模
我们一般用大写的 O() 来作为时间复杂度的记法
对于时间复杂度是怎么算的下面给出几种比较常见的计算方式与类型
第一种 O(1)
int n = 100 ;//运行一次
int sum = (1 + n)*n/2;//运行一次
System.out.println(sum);//运行一次
上面一共有三次操作 但是每次操作都是单条操作也就是指运行一次不管运行多少次,次数都是一个常数 所以我们都将这种的时间复杂度称为O(1)
第二种 O(n)
for (int i = 1; i <= n; i++){
sum = sum + i;//运行一次
}
这里的sum = sum+i;是运行了一次的但是for循环是必须要循环n次所以我们将其的时间复杂度称为O(n) ,通常大部分的O(n)算法也被称之为线性算法
第三种 O(logn)
int i=1;
while (i<=n)
i=i*2;
上面的 i = i*2 运行了一次 但是每次的 i 都是 *2 我们的跳出循环条件 也就是时间运行的结束点是以i<=n来作为结束的,当每次i乘以2的时候也就离n更近了,所以我们可以得出 多少个2 相乘等于n 也就是
2^x = n 也就是log2^n
则得出 时间复杂度为 O(log2n)
第四种O(n^2)
for(int j = 1 ; j<=n ;j++) {
for (int i = 1; i <= n; i++){
sum = sum + i;//运行一次
}
}
上面的可以看出是有两个for循环,里面的循环我们刚才已经分析过了,为O(n)的时间复杂度,内循环再次循环n次也就是n^2所以这段代码时间复杂度为 O(n^2)
上面四种只是最基本的时间复杂度计算,下面附上一张计算时间复杂度的参考表
最后还要说一点就是,我们上面算的都是时间复杂度的最坏情况,完成这段代码的运算最坏情况下需要的时间,应该有的算法情况有着不确定性,有可能是第一次就算出来了也有可以能最后一次也就是第n次才算出,所以我们算的一般都是时间复杂度的最坏情况