时间复杂度和空间复杂度

时间复杂度和空间复杂度

案例来自漫画算法

时间复杂度

时间复杂度是统计代码基本执行次数的,下面用生活中的4个场景来进行说明。

场景1

一个长度为10 cm的面包,每3分钟吃掉1 cm,那么吃掉整个面包需要多久?

答案自然是3×10即30分钟。

如果面包的长度是n cm呢?

此时吃掉整个面包,需要3乘以n即3 n分钟。

如果用一个函数来表达吃掉整个面包所需要的时间,可以记作T(n) = 3 n,n为面 包的长度。

T(n) = 3n,执行次数是线性的。

void eat1(int n){
    for(int i=0; i<n; i++){;
       System.out.println("等待1分钟"); 
       System.out.println("等待1分钟"); 
       System.out.println("吃1cm 面包"); 
    } 
}

场景2

1个长度为16 cm的面包,每5分钟吃掉面包剩余长度的一半, 即第5分钟吃掉8 cm,第10分钟吃掉4 cm,第15分钟吃掉2 cm……那么把面包吃得 只剩1 cm,需要多久呢?

这个问题用数学方式表达就是,数字16不断地除以2,那么除几次以后的结果等 于1?这里涉及数学中的对数,即以2为底16的对数。log_2 16

因此,把面包吃得只剩下1 cm,需要5×log_2 16即20分钟。

如果面包的长度是n cm呢?

此时,需要5乘以log _2 n即5log _2 n分钟,记作T(n) = 5 log_2 n

 void eat2(int n){ 
     for(int i=n; i>1; i/=2){                     
         System.out.println("等待1分钟");
         System.out.println("等待1分钟");         
         System.out.println("等待1分钟");         
         System.out.println("等待1分钟");         
         System.out.println("吃一半面包"); 
     }
}

场景3

1个长度为10 cm的面包和1个鸡腿,每2分钟吃掉1个鸡腿。 那么吃掉整个鸡腿需要多久呢?

答案自然是2分钟。

因为这里只要求吃掉鸡腿,和10 cm的面包没有关系。

如果面包的长度是n cm呢?

无论面包多长,吃掉鸡腿的时间都是2分钟,记作T(n) = 2。

 void eat3(int n){
     System.out.println(" 等待1分钟"); 
     System.out.println(" 吃1个鸡腿");
 }

场景4

1个长度为10 cm的面包,吃掉第1个1 cm需要1分钟时间,吃 掉第2个1 cm需要2分钟时间,吃掉第3个1 cm需要3分钟时间……每吃1 cm所花的时间就 比吃上一个1 cm多用1分钟。

吃掉整个面包需要多久呢?

答案是从1累加到10的总和,也就是55分钟。

如果面包的长度是n cm呢?

根据高斯算法,此时吃掉整个面包需要 1+2+3+…+(n-1)+ n 即(1+n)×n/2分 钟,也就是0.5 * n * 2 + 0.5 * n分钟,记作T(n) = 0.5 * n * 2 + 0.5 * n。

void eat4(int n){
    for(int i=0; i<n; i++){
        for(int j=0; j<i; j++){ 
            System.out.println("等待1分钟");}
            System.out.println("吃1cm 面包");
    }
}

上面所讲的是吃东西所花费的时间,这一思想同样适用于对程序基本操作执行次数的统计。

渐进时间复杂度

有了基本操作执行次数的函数T(n),是否就可以分析和比较代码的运行时间了 呢?还是有一定困难的。

例如算法A的执行次数是T(n)= 100 * n,算法B的执行次数是T(n)= 5n^2,这两个 到底谁的运行时间更长一些呢?这就要看n的取值了。

因此,为了解决时间分析的难题,有了渐进时间复杂度(asymptotic time complexity)的概念,其官方定义如下。

若存在函数f(n),使得当n趋近于无穷大时,T(n)/f(n)的极限值为不等于零的 常数,则称f(n)是T(n)的同数量级函数。记作T(n)=O(f(n)),称为O(f(n)),O为算 法的渐进时间复杂度,简称为时间复杂度。

因为渐进时间复杂度用大写O来表示,所以也被称为大O表示法

对于上述四种场景,

  • T(n) = 3*n
    最高阶项为3*n,省去系数3,则转化的时间复杂度为:T(n)=O(n)。
  • T(n) = 5logn
    最高阶项为5logn,省去系数5,则转化的时间复杂度为:T(n) =O(logn)。
  • T(n) = 2,
    只有常数量级,则转化的时间复杂度为:T(n) =O(1)。
  • T(n) = 0.5*n^2+ 0.5*n
    最高阶项为0.5*n^2,省去系数0.5,则转化的时间复杂度为:T(n) =O(n^2)。

这4种时间复杂度究竟谁的程度执行用时更长,谁更节省时间呢?

当n的取值足 够大时,不难得出下面的结论:

O(1)<O(logn)<O(n)<O(n^2)

在编程的世界中有各种各样的算法,除了上述4个场景,还有许多不同形式的时 间复杂度,例如:

O(nlogn)、O(n^3)、O(mn)、O(2^n)、O(n!)

空间复杂度

用来描述一个算法所占空间的大小,叫空间复杂度

空间复杂度计算

常量空间

当算法的存储空间大小固定,和输入规模没有直接的关系时,空间复杂度记 作O(1)。例如下面这段程序:

void fun1(int n){    
    int var = 3;
    … 
}

线性空间

当算法分配的空间是一个线性的集合(如数组),并且集合大小和输入规模n成 正比时,空间复杂度记作O(n)。
例如下面这段程序:

void fun2(int n){
    int[] array = new int[n];
    … 
}

二维空间

当算法分配的空间是一个二维数组集合,并且集合的长度和宽度都与输入规模n 成正比时,空间复杂度记作O(n^2)。
例如下面这段程序:

void fun3(int n){
    int[][] matrix = new int[n][n];
    … 
}

递归空间

递归是一个比较特殊的场景。虽然递归代码中并没有显式地声明变量或集合, 但是计算机在执行程序时,会专门分配一块内存,用来存储“方法调用栈”。

“方法调用栈”包括进栈和出栈两个行为。

当进入一个新方法时,执行入栈操作,把调用的方法和参数信息压入栈中。
当方法返回时,执行出栈操作,把调用的方法和参数信息从栈中弹出。

下面这段程序是一个标准的递归程序:

void fun4(int n){
    if(n<=1){
        return;
    }
    fun4(n-1);
    … 
}

执行递归操作所需要的内存空间和递归的深度成正比。纯粹的递归操作的空间复杂度也是线性的,如果递归的深度是n,那么空间复杂度就是O(n)。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容