目录
时间复杂度
空间复杂度
先简要介绍一下:
算法复杂度分为时间复杂度和空间复杂度。其作用:时间复杂度是指执行这个算法所需要的计算工作量;而空间复杂度是指执行这个算法所需要的内存空间。时间和空间(即寄存器)都是计算机资源的重要体现,而算法的复杂性就是体现在运行该算法时的计算机所需的资源多少。
在面试的时候,如果面试官问你,你知道什么是时间复杂度和空间复杂度吗?
你会吗???,虽然这东西天天在嘴巴上跑,像我一样吊儿郎当,肯定不会,哈哈哈哈,但是要我用一个很通俗易懂的语言来讲讲,我真的真的不知道。
那么我们就来说说吧:
时间复杂度和空间复杂度一般都是在算法上出现的一个衡量值,是对一个算法是否高效的一个标准。其实之前一直有个误解,就是时间复杂度就是算法的运行周期的时间。其实这是错误的。并且对于算法来说,一个for就是一个算法,一个1-2-x-y=1,也是一个算法,对于我们了解的八大排序算法,都是算法,对于根本来说,八大排序算法都是循环本质实现的。
时间复杂度
对于时间复杂度是指的算法语句的执行次数。一个算法语句的执行次数最终都是可以通过函数f(n)来形容的。
1:算法的时间复杂度反映了程序执行时间随输入规模增长而增长的量级,在很大程度上能很好地反映出算法的优劣与否;
2:算法执行时间需要依据该算法编制的程序在计算机上执行运行时所消耗的时间来度量,度量方法有两种,事后统计方法和事前分析估算方法,因为事后统计方法更多的依赖计算机的硬件,软件等环境因素,有时容易掩盖算法本身的优劣。因此常常采用事前分析估算的方法;
3:一个算法是由控制结构(顺序,分支,循环三种)和原操作(固有数据类型的操作)构成的,而算法时间取决于两者的综合效率;
4:一个算法花费的时间与算法中语句的执行次数成正比,执行次数越多,花费的时间就越多。一个算法中的执行次数称为语句频度或时间频度。记为T(n);
5:在时间频度中,n称为问题的规模,当n不断变化时,它所呈现出来的规律,我们称之为时间复杂度(其实在这中间引入了一个辅助函数f(n),但它与t(n)是同数量级函数,我们且先这样理解。)
6:在各种算法中,若算法中的语句执行次数为一个常数,则时间复杂度为O(1);同时,若不同算法的时间频度不一样,但他们的时间复杂度却可能是一样的,eg:T(n)=n^2+2n+4 与 T(n)=4n^2+n+8,他们的时间频度显然不一样,但他们的时间复杂度却是一样的,均为O(n^2),时间复杂度只关注最高数量级,且与之系数也没有关系。
就比如:
int i = 0;
while(i < 100){
i++;
}
这里的i++就是算法语句,那么其f(n) = 100 - i -1;就可以知道他的时间复杂度了。
时间复杂度为:
(1)O(1)
用大Ο记号表示算法的时间性能。
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
System.out.println("-");
}
}
这输出语句就是算法语句,那么f(n)就是:f(n) = n * n = n^2的平方。
时间复杂度为 :
O(n^2)
int i = 0;
while(i < n){
i++;
}
这里的i++;为算法语句,那么f(n)就是 f(n) = n - i - 1;
时间复杂度为:
O(n)
那么理解了如何将算法语句执行次数通过函数表示出来,时间复杂度一眼就可以看出来了,有以下几条规则
(1)选取f(n)系数最大项,如果系数都负数,那么就选择常数,那么时间复杂度就是常数阶O(1)
(2)跟进第一条拿到系数最大项后,将系数化为1,剩下的就是时间复杂度。
(3)一个算法可能有多条算法语句,即可能有多个循环判断,时间复杂度的计算考虑最坏情况,即取最大值。
空间复杂度
空间复杂度就是一个算法在运行过程中临时占用的存储空间大小,换句话说,就是被创建次数最多的变量,他被创建了多少次,那么这个算法的空间复杂度就是多少。
for(int i = 0; i < n; i++){
int temp = i;
}
and
int temp = 0;
for(int i = 0; i < n; i++){
temp = i;
}
那么两者的区别很明显的了,前者的空间复杂度就是O(n),因为temp变量再不断的被创建n次。那么后者就是在循环之前就声明好了一个变量,开辟了一个内存空间,那么在循环中,只是不断的将此变量的地址值指向i的内存地址。只是一个引用的操作,所以,如果算法语句中,有创建对象,那么这个算法的时间复杂度和空间复杂度一般来说就是一致的。
1:空间复杂度是对一个算法在运行过程中临时占用存储空间大小的量度;
2:一个算法在计算机上占用的内存包括:程序代码所占用的空间,输入输出数据所占用的空间,辅助变量所占用的空间这三个方面,程序代码所占用的空间取决于算法本身的长短,输入输出数据所占用的空间取决于要解决的问题,是通过参数表调用函数传递而来,只有辅助变量是算法运行过程中临时占用的存储空间,与空间复杂度相关;
3:通常来说,只要算法不涉及到动态分配的空间,以及递归、栈所需的空间,空间复杂度通常为0(1);
总的来说:
对于一个算法,其时间复杂度和空间复杂度往往是相互影响的。
当追求一个较好的时间复杂度时,可能会使空间复杂度的性能变差,即可能导致占用较多的存储空间;反之,求一个较好的空间复杂度时,可能会使时间复杂度的性能变差,即可能导致占用较长的运行时间。另外,算法的所有性能之间都存在着或多或少的相互影响。因此,当设计一个算法(特别是大型算法)时,要综合考虑算法的各项性能,算法的使用频率,算法处理的数据量的大小,算法描述语言的特性,算法运行的机器系统环境等各方面因素,当然,同时你还要带上你的小脑袋来去思考算法逻辑,认真钻研,才能够设计出比较好的算法滴。