之前在面试的时候,面试官问了我一句,你知道什么是时间复杂度和空间复杂度吗?
这直接给我问懵了,虽然这东西天天在嘴巴上跑,但是要我用一个很通俗易懂的语言来讲讲,我真的不知道。
那么我们就来说说吧:
时间复杂度和空间复杂度一般都是在算法上出现的一个衡量值,是对一个算法是否高效的一个标准。其实之前一直有个误解,就是时间复杂度就是算法的运行周期的时间。其实这是错误的。并且对于算法来说,一个for就是一个算法,一个1-2-x-y=1,也是一个算法,对于我们了解的八大排序算法,都是算法,对于根本来说,八大排序算法都是循环本质实现的。
时间复杂度
对于时间复杂度是指的算法语句的执行次数。一个算法语句的执行次数最终都是可以通过函数f(n)来形容的。
就比如:
int i = 0;
while(i < 100){
i++;
}
这里的i++就是算法语句,那么其f(n) = 100 - i -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的平方。
int i = 0;
while(i < n){
i++;
}
这里的i++;为算法语句,那么f(n)就是 f(n) = n - i - 1;
那么理解了如何将算法语句执行次数通过函数表示出来,时间复杂度一眼就可以看出来了,有以下几条规则
(1)选取f(n)系数最大项,如果系数都负数,那么就选择常数,那么时间复杂度就是常数阶O(1)
(2)跟进第一条拿到系数最大项后,将系数化为1,剩下的就是时间复杂度。
(3)一个算法可能有多条算法语句,即可能有多个循环判断,时间复杂度的计算考虑最坏情况,即取最大值。
根据以上3个规则,那么就可以对前三个例子分别得出对应的时间复杂度为:
(1)O(1) (2)O(n的平方) (3)O(n)
空间复杂度
空间复杂度就是一个算法在运行过程中临时占用的存储空间大小,换句话说,就是被创建次数最多的变量,他被创建了多少次,那么这个算法的空间复杂度就是多少。eg:
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的内存地址。只是一个引用的操作,所以,如果算法语句中,有创建对象,那么这个算法的时间复杂度和空间复杂度一般来说就是一致的。