这个代码的时间、空间复杂度我感觉挺难的,如果搞不懂,如何做优化(运行更快、更少使用内存空间),所以,查阅资料进行学习,主要参考资料是大话数据结构和CSDN:杨柳_的一篇文章。
原创文章参考地址:https://blog.csdn.net/qq_37375427/article/details/84594115 自己总结的很简略,主要是方便我自己学习了,大家可以参看原文*^_^*…..
1:大O
举个例子:
int cal(int n) { int sum = 0; //tfor (int i = 1; i <= n; ++i) { //t + 3nt + t sum = sum + i; } return sum; //t }
假设CPU执行一条指令的时间是一个固定的时间:t。那么执行完这个函数,用的时间是:t + t + 3nt + t + t = (3n +4)t。
所以,执行时间T(n)与每行代码执行次数成正比。
再举个例子:
int cal(int n) { int sum = 0; //tfor (int i = 1; i <= n; ++i) { //2t +3nqfor (int j = 1; j <= n; ++j) { //q = 3nt + 2t sum = sum + i * j; } }
return sum; //t }
总的执行命令:(9n^2 + 6n + 4)t 。
而大O表示法,代表着执行时间随数据规模增长的一种变化趋势,又称“时间复杂度”。
为了简化,只取最高次幂。
2:嵌套乘法法则
例如:
int cal(int n) { int ret = 0; int i = 1; for (; i < n; ++i) { ret = ret + f(i); //注意:这里嵌套调用 所以,,这里是乘法。。 } } int f(int n) { int sum = 0; int i = 1; for (; i < n; ++i) { sum = sum + i; } return sum; }
时间复杂度:O(n*n)==O(n^2);
3:常见时间复杂度(对数的时间复杂度最恶心我了。)
O(logn) O(nlogn)
i=1; while (i <= n) { i = i * 2; }
执行x次:2^x=n 得到x=log2n;
不管是以几位底的,都要记做:O(logn);
如果一段代码时间复杂度为O(logn),那么执行n次,时间复杂度就是O(nlogn);
O(nlogn)也很常见,比如归并排序、快排的时间复杂度都是O(nlogn)。
int cal(int m, int n) { int sum1 = 0; for (int i = 1; i < m; ++i) { sum1 = sum1 + i; } int sum2 = 0; for ( int j = 1; j < n; ++j) { sum2 = sum2 + j; } return sum1 + sum2; }
mn都是未知规模的变量,代码又没嵌套,所以,时间复杂度为O(m + n);
4:空间复杂度(分析比较简单)
就看和数据规模n有关不,常见的是O(1)、O(n)、O(n^2);对数的少见。
5:总结
复杂度,用来衡量代码执行效率与数据规模之间的增长关系;常见从低阶到高阶的复杂度:O(1)、O(logn)、O(n)、O(nlogn)、O(n^2);