时间复杂度和空间复杂度(二)

这节呢,主要说下,简单的时间复杂度和时间复杂度怎么一眼就看出。
下一接会具体说明最好,最坏,分担复杂度。

一、时间复杂度

例子:

1 private int  test() {
2       int count = 0;
3       for (int i = 0; i < 10; i++){
4            count +=i;
5        }
6        return  count;
7    }

忽略CPU 等其他因素的时间,大概估算下。
假设:第2句代码耗时1个单位cost_time,3-4行执行了n次,耗时为2n个cost_time,
那么整体耗时多少呢?
耗时: totlaTime = cost_time + 2n*cost_time = (2n+1)cost_time
可以看出来,所有代码的执行时间 T(n) 与每行代码的执行次数成正比。
所以就可以大概可以总结为:T(n) = O(n)
简单的分析就是,分析时间复杂度时,忽略其他一些常量参数,因为在大数量级面前,常量数据并不影响最后的结果,可以简单的认为对于单层循环而言,时间复杂度为O(n),同理2层循环便是O(n^2),其他同理.
那么对于一段代码具有单层循环和多层循环时间复杂度是多少呢,这里呢,按照最大的时间复杂度算就对了。
比如

private int  test() {
        int count = 0;
        int count1 = 0;
        for (int i = 0; i < 10; i++){
            count +=i;
        }

        for (int i = 0 ;i <10;i++){
            for (int j =0;j < 10 ; j ++){
                count1 += j * i;
            }
        }
        return  count;
    }

那么这个的时间复杂度就是: O(n^2)
常见的时间复杂度:

O(1)(常数阶)、O(logn)(对数阶)、O(n)(线性阶)、O(nlogn)(线性对数阶)、O(n^2)(平方阶)、O(n^3)(立方阶)

注意:
1.O(1) 并不是只有一行代码,时间复杂度就是O(1),O(1) 只是常量级时间复杂度的一种表示方法,比如下面代码是2行,时间复杂度也是O(1)。只要代码的执行时间不随 n 的增大而增长,这样代码的时间复杂度我们都记作 O(1)。

int i = 3;
int j = 99;
  1. 常见的O(logn)(对数阶) 是怎么样的形式呢?
int i =1;
while(i < n ){
  i = i * 3 ;
}

从代码中可以看出,变量 i 的值从 1 开始取,每循环一次就乘以 3。当大于 n 时,循环结束。
回忆高中时的内容,是不是就是一个等比数列:3 9 27 71..... k => 3^0 3^1 3^2 3^3 ...... 3^x,
3^x = n => n = log3n 忽略常数,可以得出 logn

二、空间复杂度

空间复杂度指的是除特定空间外,重新申请开辟的空间,以代码为例

 private int[] test(int n){
        
        int[] a = new int[n];

        for (int i =0; i <n; ++i) {
            a[i] = i * i;
        }
        return a;
    }

考虑空间复杂度时还是忽略一些常量数据,比如可以看到申请一个大小为n的数据空间,和一个常量的空间i,忽略常量,那么只剩n个内存空间,那么可以大概说明空间复杂度为O(n),用算法举例更具说服力。

image.png

映射上节的纯文字叙述:

复杂度分析方法
  • 单段代码看高频:比如循环。
  • 多段代码取最大:比如一段代码中有单循环和多重循环,那么取多重循环的复杂度。
  • 嵌套代码求乘积:比如递归、多重循环等。
  • 多个规模求加法:比如方法有两个参数控制两个循环的次数,那么这时就取二者复杂度相加。

第三节传送门:https://www.jianshu.com/p/0314afcde9b0

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。