算法:时间复杂度和空间复杂度
时间复杂度和空间复杂度
1.时间复杂度 Big O notaion
- O(1):Constant Complexity 常数复杂度
- O(log n): Logarithmic Complexity 对数复杂度
- O(n): Linear Complexity 线性时间复杂度
- O(n^2): N squeare Complexity 平方
- O(n^3): N cubic Complexity 立方
- O(2^n): Expoential Growth 指数
- O(n!): Factorial 阶乘
注意:只看最高复杂度的运算
如何计算时间复杂度
最简单的方式就是查看函数运行了多少次
O(1)
int n = 1000;
Console.WriteLine(n);
这种运行了一次的就是O(1)时间复杂度
int n = 1000;
Console.WriteLine(n);
Console.WriteLine(n);
Console.WriteLine(n);
这里虽然运行了三次但是与属于O(1)时间复杂度,这里的1代表常数
O(N)
for(int i=0;i<n;i++) { Console.WriteLine(n); }
这里就是普通的O(n)时间复杂度,N决定了循环的次数
O(N^2)
for(int i=0;i<n;i++) for(int i=0;i<n;i++) { Console.WriteLine(n); }
1.这是一个嵌套循环,如果N=20;那么循环次数就是20*20= 400,双层嵌套时间复杂度是平方
2.如果不是嵌套的循环,而是并列的循环,那么时间复杂度是什么呢?——当然是O(n)
O(log(n))
for(int i=0;i<n;i*2) { Console.WriteLine(n); }
假设N为4,那么循环只会执行两次,这就是对数时间复杂度O(log(n))
O(k^n)
int fib(int n) { if(n < 2) return n; return fib(n-1) + fib(n - 2); }
递归程序如何计算时间复杂度,答案是K的N次方,这里K是一个常数,也就是说复杂度是指数级的
时间复杂度曲线
可以看出N如果在5以内不同的时间复杂度其实都差不多,但是当N开始扩大,会发现指数级涨的是非常快的,也就是说一个程序如果能够优化时间复杂度从2的n次方降到n的方法的话,从曲线上说,当N在比较大的时候,得到的收益是非常高的。N越高,后面的差别越大。
- 在写程序时,一定要对自己的程序时间和空间复杂度有所了解,而且是养成习惯,写完了之后下意识地分析出程序的时间和空间复杂度
- 能够用最简洁的时间空间复杂度完成能够,是顶尖选手的职业素养:)
递归时间复杂度的计算方法
递归的时间复杂度都是指数级别的,一般使用四大定理来计算
- Binary search 二分查找是Log(n)的时间复杂度
二分查找一般在有序序列中使用
- Binary tree traversal 二叉树是O(N)的时间复杂化度
二叉树的遍历每个节点都会被访问到所以是O(N)的时间复杂度,取决于N节点的个数
- Optimal serach matrix 二维矩阵是O(n)的时间复杂化度
- Merge sort 归并排序O(nlongn)的时间复杂化度
空间复杂度
如果是长度为10的数组 空间复杂度就是为10
如果是二位数组,且数组长度为N的平方,那么空间复杂度空间复杂度就是N的平方
如果是递归,那么空间复杂度就是递归的深度