文章目录
参考文章:
https://juejin.im/entry/5b38f3b6e51d4558de5c0139
https://blog.csdn.net/zolalad/article/details/11848739
常用数据结构和算法时间复杂度速查表
时间复杂度
常见的算法时间复杂度由小到大依次为:
Ο(1)<Ο(logn)<Ο(n)<Ο(nlogn)<Ο(n2)<Ο(n3)<…<Ο(2^n)<Ο(n!)
Ο(1)
表示基本语句的执行次数是一个常数,一般来说,只要算法中不存在循环语句,其时间复杂度就是Ο(1)
其中Ο(logn)、Ο(n)、 Ο(nlogn)、Ο(n2)和Ο(n3)称为多项式时间,计算机科学家普遍认为(即多项式时间复杂度的算法)是有效算法,
Ο(logn)
如果循环中有二分则为O(logn), 再一个例子:对半查找,叫做二分
for (int i = 0; i < n; i = i*2)
{
cout<<"d";
}
int i = 1;
while (i < n)
{
i = i*2;
}
O(N)
最基础的循环执行n次
for (int i = 0; i < n; i++)
{
cout<< "d";
}
O(nlogN)
就是O(logn)代码循环N遍 也就是两重循环,一重循环为n,第二重循环为logN
for (int i = 0; i < n; i++)
{
//二分查找,或者O(logN)的算法
while (i < n)
{
i = i*2;
}
}
O(n^2) O(n³)
双重O(n)嵌套
O(n³)相当于三层n循环,其它的类似。N的K次方就是n的K次循环
后面比如Ο(2^n) , Ο(n!)的时间复杂度太高,一般就不考虑使用了。
一个经验规则:其中c是一个常量,如果一个算法的复杂度为Ο(1)<Ο(logn)<Ο(n)<Ο(nlogn),那么这个算法时间效率比较高Ο(n2)<Ο(n3)几个则差强人意。,如果是2n ,3n ,n!,则不要考虑了。
如何计算时间复杂度
可以假设n为5,看代码执行几行,然后假设n为10看代码执行几行。由此得到时间复杂度。
举例:计算1+2+3….n
第一种:for(int I = 1;I <= n;i++){ sum+=I;} 他的时间复杂度为代码执行N次,为O(n)
第二种:求和公式n*(n+1)/2 则O(1)
举例:斐波那契数列。1,1,2,3,5,8,13… F(n) = F(n-1) + F(n-2)
第一种:递归程序,def fib(n) { if(n ==1) return 1; return fib(n-1) + fib(n-2) }
递归时,时间复杂度: N =1执行1行, n=2执行3行 n=3执行4行 n=4执行8
N = 5执行13
类似于2的N次方的复杂度 空间复杂度为S(1)
第二种方法:动态规划使用临时变量移动O(N) S(1)
int fib(int n) {
if (n < 2) {
return n;
}
int a = 0;
int b = 1;
int sum = 0;
for (int i = 2; i <= n; i++) {
sum = (a + b) % 1000000007;
a = b;
b = sum;
}
return sum;
}
一般我们讨论的时间复杂度都是最坏时间复杂度
我们可以看到冒泡,交换,选择,插入时间复杂度一样为n2所以他们的性能差不多
而基数,希尔,快速,归并,堆排序,时间复杂度为nlogn速度就要要快一些
空间复杂度
空间复杂度(Space Complexity)是对一个算法在运行过程中临时占用存储空间大小的量度
我们用 S(n) 来定义。
空间复杂度比较常用的有:O(1)、O(n)、O(n²)
我们在写代码时,完全可以用空间来换取时间,比如说,要判断某某年是不是闰年,你可能会花一点心思写了一个算法,而且由于是一个算法,也就意味着,每次给一个年份,都是要通过计算得到是否是闰年的结果。还有另一个办法就是,事先建立一个有2 050个元素的数组(年数略比现实多一点),然后把所有的年份按下标的数字对应,如果是闰年,此数组项的值就是1,如果不是值为0。
可表示为 O(1)
举例:
int i = 1;
int j = 2;
++i;
j++;
int m = i + j;
代码中的 i、j、m 所分配的空间都不随着处理数据量变化,因此它的空间复杂度 S(n) = O(1)
O(1)是说数据规模和临时变量数目无关,并不是说仅仅定义一个临时变量。举例:无论数据规模多大,我都定义100个变量,这就叫做数据规模和临时变量数目无关。就是说空间复杂度是O(1)。
空间复杂度 O(n)
我们先看一个代码:
int[] m = new int[n]
for(i=1; i<=n; ++i)
{
j = i;
j++;
}
这段代码中,第一行new了一个数组出来,这个数据占用的大小为n,