文章目录
如何判断程序的复杂程度:时间和空间复杂度
1. 时间复杂度:
使用大O表示法来表示程序的时间复杂度
常见的7种时间复杂度(复杂度由低到高排序)
-
O(1):常数时间复杂度
-
O(log(n): 对数时间复杂度
-
O(n): 线性时间复杂度
-
O(n^2):平方时间复杂度
-
O(n^3):立方时间复杂度
-
O(k^n):指数时间复杂度,k表示常数
-
O(n!):阶乘时间复杂度
ps:
-
这里我们并不考虑前边的系数;O(1) 并不表示复杂度为1,也可以 是2、3等常数;O(n)表示程序运行了n次或者2n、3n次;以此类推其他时间复杂度
-
时间复杂度的判断,以一段代码的最高复杂度为准;
如何判断一段代码的时间复杂度
简而言之就是看内部某段代码的执行次数
-
O(1):常数复杂度
-
int n = 1; System.out.println(n); -
int n = 1; System.out.println(n); System.out.println(n+1) System.out.println(n+2)
-
-
O(n):线性时间复杂度
-
for (int j = 0; j < n; j++) { System.out.println(j); } -
for (int i = 0; i < n; i++) { System.out.println(i); } for (int j = 0; j < n; j++) { System.out.println(j); }
-
-
O(n^2):平方时间复杂度
-
for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { System.out.println(i + j); } }
-
-
O(n^3):立方时间复杂度
-
for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { for (int k = 0; k < n; k++) { System.out.println(i + j); } } }
-
-
O(log(n)): 对数时间复杂度
这里演示的是以2为底n的对数
-
for (int i = 0; i < n; i = i * 2) { System.out.println(i); }
-
-
O(2^n):指数时间复杂度
-
/** * 递归求斐波那契数列的第n项;可以通过画运行树的方式获得时间复杂度 */ int fib(int n) { if (n < 2) return n; return fib(n - 1) + fib(n - 2); }
-
-
O(n!):阶乘时间复杂度
- todo
小练习1:求和计算1~n的和
-
O(n)
int y = 2; for (int i = 0; i < n; i++) { y+=i; } -
O(1)
使用了求和公式:sum = n(n+1)/2
int y = 2; for (int i = 0; i < n; i++) { y+=i; }
小练习2:求斐波那契数列
-
O(2^n):
int fib(int n) { if (n < 2) return n; return fib(n - 1) + fib(n - 2); } -
O(n):该方法比递归要快得多
int fib2(int n) { if (n == 1 || n == 2) { return 1; } int a = 1, b = 1, result = 0; for (int i = 3; i <= n; i++) { result = a + b; a = b; b = result; } return result; }
主定理
常用算法中的应用
| 算法 | 递回关系式 | 运算时间 |
|---|---|---|
| 二分搜寻算法 | ![]() | ![]() |
| 二叉树遍历 | ![]() | ![]() |
| 最佳排序矩阵搜索(已排好序的二维矩阵) | ![]() | ![]() |
| 合并排序 | ![]() | ![]() |
所有排序的最优算法都是O(nlog(n))
2. 空间复杂度
如何判断一段代码的空间复杂度
主要通过两部分进行判断:
-
数组的长度
如果代码中应用了数组,那么数组的长度,基本上就是空间复杂度;
e:一维数组的空间复杂度是O(n);二维数组的空间复杂度是O(n^2) -
递归的深度
如果代码中有递归,那么递归的深度,就是代码的空间复杂度的最大值
ps:如果代码中既有数组,又有递归,那么两者的最大值就是代码的空间复杂度
leecode有个爬楼梯的复杂度分析情况;可以进行练习
3. 数组和链表的时间复杂度分析
数组
随机增加:O(n)
随机查询:O(1)
随机删除:O(n)
链表
随机增加:O(1)
随机查询:O(n)
随机删除:O(1)
跳表
跳跃表(skiplist)是一种随机化的数据, 由 William Pugh 在论文《Skip lists: a probabilistic alternative to balanced trees》中提出, 跳跃表以有序的方式在层次化的链表中保存元素, 效率和平衡树媲美 —— 查找、删除、添加等操作都可以在对数期望时间下完成, 并且比起平衡树来说, 跳跃表的实现要简单直观得多。
简单来说,跳跃表是有序链表的一种扩展,在有序列表的基础上进行了升维处理


以上图片来自公众号:程序员小灰
随机增加:O(log(n))
随机查询:O(log(n))
随机删除:O(log(n))
本文介绍程序的时间复杂度和空间复杂度概念,详细分析了不同类型的复杂度及其在常见算法中的应用,包括数组、链表及跳表的时间复杂度对比。








1017

被折叠的 条评论
为什么被折叠?



