Java·时间复杂度与空间复杂度
复杂度解释与表达
复杂度解释
算法复杂度是指算法在编写成可执行程序后,运行时所需要的资源,资源包括时间资源和内存资源。
同一问题可用不同算法解决,而一个算法的质量优劣将影响到算法乃至程序的效率。算法分析的目的在于选择合适算法和改进算法。一个算法的评价主要从时间复杂度和空间复杂度来考虑。
- 时间复杂度:一个算法执行所耗费的时间,从理论上是不能算出来的,必须上机运行测试才能知道。但我们不可能也没有必要对每个算法都上机测试,只需知道哪个算法花费的时间多,哪个算法花费的时间少就可以了。并且一个算法花费的时间与算法中语句的执行次数成正比例,哪个算法中语句执行次数多,它花费时间就多。
- 空间复杂度:空间复杂度是对一个算法在运行过程中临时占用存储空间大小的量度。一个算法的空间复杂度只考虑在运行过程中为局部变量分配的存储空间的大小,包括参数表中形参变量分配的存储空间和在函数体中定义的局部变量分配的存储空间。
复杂度表达(常见)
- O(1):Constant Complexity 常数复杂度
- O(log n):Logarithmic Complexity 对数复杂度
- O(n):Linear Complexity 线性时间复杂度
- O(n2):N square Complexity 平方
- O(n3):N cubic Complexity 立方
- O(2n):Exponential Growth 指数
- O(n!):Factorial 阶层
注意:表达并不考虑系数,且只看最高复杂度的运算
时间复杂度分析
常见时间复杂度
O(1)
//第一种
int num = 100;
System.out.println("输出:" + num);
//第二种
int num = 100;
System.out.println("输入:" + num);
System.out.println("输出:" + num);
System.out.println("无论时间复杂度是O(1)还是O(3),它们都属于O(1)级别的复杂度");
O(n)
//一层从一到n的循环,时间复杂度是 O(n),如果多个同时执行,时间复杂度依然是 O(n)
for(int i = 0; i < n; i++ ){
System.out.println("输出:" + i);
}
O(nk)
//k层从一到n的嵌套循环,时间复杂度是 O(nk),如果是同时执行,时间复杂度依然是 O(n)
for(int i = 0; i < n; i++ ){
for(int j = 0; j < n; j++ ){
System.out.println(" " + i + j + " ");
}
}
O(log n)
注:当 n 为2的时候执行一次,当 n 为4的时候执行二次,当 n 为8的时候执行三次,以此类推可知,规则为 log2n,故复杂度是 O(log n),底数默认是 2 。
for(int i = 1; i < n; i = i * 2){
System.out.println("输出:" + i );
}
递归时间复杂度
O(2n)
斐波那契数列“递归”求第 n 项,由图可知最终计算次数为指数级。
int fib(n){
if(n<2) return n;
return fib(n-1) + fib(n-2);
}
![斐波那契数列计算树形](https://img-blog.csdnimg.cn/20201117140545564.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzQ1MzA0MTYw,size_16,color_FFFFFF,t_70#pic_center) 优化可以加入缓存,把已经计算过的结果缓存起来。
算法复杂度举例
算法 | 时间复杂度 |
---|---|
二分法查找 | O(log n) |
二叉树查找 | O(n) |
普通一维数组 | O(n) |
普通二位数组 | O(n2) |
有序二位数组 | O(n) |
归并排序 | O(n log n),时间复杂度最优的排序算法 |
图/二叉树遍历 | O(n),每个结点访问且仅访问一次 |
深度优先/广度优先 | O(n),每个结点访问且仅访问一次 |
简单时间复杂度优化
算法解决步骤:
- 确认题意理解准确无误
- 想出所有能想到的解决思路
- 比较时间和空间复杂度,寻找最优解
- 写代码、测试数据
例题:从 1 + 2 + 3 + …+ n
O(n):利用一层 for 循环,从 1 加到 n
O(1):利用公式 f = n(n+1)/2
时间复杂度曲线
横坐标是数组或集合的大小,纵坐标是时间复杂度的大小,表现纵坐标随横坐标变化而变化的情况形势。
空间复杂度分析
- 数组:算法过程中开的数组的大小(一维:n,二维:n2);
- 递归的深度:深度的最大值(可参考斐波那契数列),如果有递归又开了数组,则是两者的最大值。
一文一哲理
真正的朋友,不在于花言巧语,而是关键时刻拉你的那只手