目录
- 1. 时间复杂度
- 1.1 例子
- 1.2 概念的说明
- 1.3 常见的时间复杂度介绍
- 1.3.1 ** O ( l o g 2 n ) O(log_2n) O(log2n)**
- 1.3.2 ** O ( n l o g 2 n ) O(nlog_2n) O(nlog2n)**
- 1.4 常用的时间复杂度按照耗费的时间从小到大排列
- 2. 空间复杂度
1. 时间复杂度
1.1 例子
我们先来看一个简单的Java例子,来感受下时间复杂度的计算
public class Java11Test {
public static void main(String[] args) {
int[] array={3,7,9,1,4,6,2,8,5,0};
(arraySearch(array, 10, 6)); // 5
(arraySearch(array, 10, 66)); // -1
}
// 查找成功返回该元素的index, 失败返回-1
public static int arraySearch(int[] array, int valueNumber, int value) {
for(int i = 0; i < valueNumber; i++) { // 1次 n+1次 n次
if(array[i] == value) { // n次
return i; // 1次
}
}
return -1;
}
}
则arraySearch
函数的时间复杂度T(n) = O(f(n)) = O(1 + (n + 1) + n + n + 1) = O(3n + 3) = O(n)
1.2 概念的说明
- 评估角度:一个算法通常有最理想情况、平均情况、最糟糕情况,我们一般只考虑最糟糕情况
- f(n):一个算法运行的精确次数,如上面的例子,数据集合的大小为n, 则f(n) = 3n + 3
- O(f(n)):精确次数===>渐进次数,因为我们通常考虑n趋于无穷大的情况,具体的规则如下:
- 当f(n)为常数时,如f(n) = 10,则O(f(n)) = O(10) = O(1)
- 当f(n)为多项式时,只取最高阶项,如f(n) = 2 n 2 + n + 3 2n^2 + n + 3 2n2+n+3,则O(f(n)) = O( 2 n 2 2n^2 2n2)
- 当f(n)有乘常数,则去除常数,如f(n) = 2 n 2 2n^2 2n2,则O(f(n)) = O( n 2 n^2 n2)
- 什么是时间复杂度:一个算法运行所需要的时间,但不同的服务器所需的时间不同,通常采用一个算法运行的渐进次数来表示,即T(n),n是数据集合的大小,表示公式为T(n) = O(f(n))
1.3 常见的时间复杂度介绍
1.3.1 O ( l o g 2 n ) O(log_2n) O(log2n)
程序示例:
int i = 1;
while (i < n) {
i = i * 2;
}
在while循环里面,每次都将i乘以 2,乘完之后,i 距离n就越来越近了。假设循环x次之后,i就大于n了,此时这个循环就退出了,也就是说2的x次方等于n,那么x = l o g 2 n log_2n log2n。因此这个代码的时间复杂度为: O ( l o g 2 n ) O(log_2n) O(log2n)。 当代码中i = i * 3 ,则时间复杂度是 O ( l o g 3 n ) O(log_3n) O(log3n)
1.3.2 O ( n l o g 2 n ) O(nlog_2n) O(nlog2n)
程序示例:
for(int m = 1; m < n; m++) {
int i = 1;
while (i < n) {
i = i * 2;
}
}
将时间复杂度为 O ( l o g 2 n ) O(log_2n) O(log2n)的代码循环n遍的话,那么它的时间复杂度就是 O ( n l o g 2 n ) O(nlog_2n) O(nlog2n)
1.4 常用的时间复杂度按照耗费的时间从小到大排列
O(1) < O(log n) < O(n) < O(n logn) < O( n 2 n^2 n2) < O( n 3 n^3 n3) < O( 2 n 2^n 2n) < O(n!)
其中 l o g k n log_kn logkn渐进为logn
2. 空间复杂度
空间复杂度(Space Complexity)是对一个算法在运行过程中临时占用存储空间大小的量度。有的算法需要占用的临时工作单元数与解决问题的规模n有关,它随着n的增大而增大,当n较大时,将占用较多的存储单元
在大多数应用场景,一个好的算法更看重时间复杂度,而空间复杂度只要合理即可