时间复杂度、空间复杂度
一、时间复杂度 Big O notation
O(1): Constant Complexity 常数复杂度
O(log n): Logarithmic Complexity 对数复杂度
O(n): Linear Complexity 线性时间复杂度
O(n^2): N square Complexity 平房
O(n^3): N cubic Complexity 立方
O(2^n): Exponential Growth 指数
O(n!): Factorial 阶乘
注意:只看最高复杂度的运算
要求:
- 写完程序后注意到时间复杂度和空间复杂度
- 用最简洁的空间和时间复杂度完成这段程序
二、递归下的时间复杂度
-
画出递归状态的递归树
-
F(n) = F(n - 1) + F(n - 2)
-
面试(直接用递归)
-
int fib(int n) { if (n < 2) return n; return fib(n - 1) + fib(n - 2); } --- 时间复杂度:O(k^n) 原因:每次循环的展开会是上次的两倍 注意:递归时有重复计算,因此可以加缓存来避免重复计算
-
-
-
主定理 Master Theorem
- 用来解决所有递归的函数
- 任何一个分治/递归的函数都可算出时间复杂度
- 实际可用的关键4种
- 二分查找:数列本身有序 - O(log n)
- 二叉树的遍历:每个节点都会切仅访问一次 - O(n)
- 有序二维矩阵中进行二分查找:O(n)
- 归并排序:因为所有排序的最优的办法就是nlogn - O(nlog n)
-
思考题
- 二叉树遍历 - 前序、中序、后序:时间复杂度是多少?
- 图的遍历:时间复杂度是多少?(答案和原理同上)
- 搜索算法:DFS深度优先、BFS广度优先时间复杂度是多少?(答案和原理同上)
- 二分查找:时间复杂度是多少?
三、空间复杂度
1、数组的长度
- 如果你的代码开了数组,那么数组的长度,基本上就是空间复杂度
- 一维数组:O(n)
- 二维数组:O(n^2)
2、递归深度(特殊说明)
- 递归最深的深度就是空间复杂度的最大值
3、爬楼梯问题
-
直接递归
- 时间复杂度 - O(2^n)
- 空间复杂度 - O(n)
-
记忆化搜索 - 加缓存的递归
- 时间复杂度 - O(n)
- 空间复杂度 - O(n)
-
动态规划
- 时间复杂度 - O(n)
- 空间复杂度 - O(n)
-
动态规划 + 内存优化
- 时间复杂度 - O(n)
- 空间复杂度 - O(1)