算法的时间复杂度和空间复杂度

概述

算法(Algorithm):是指用来操作数据、解决问题的一组方法。对于同一问题,使用不同的算法,得到最终的结果是一样的。但在过程中消耗的资源和时间却有很大的区别。
我们通过时间空间两个维度去考量算法之间的优劣。

  • 时间维度:是指执行当前算法所消耗的时间,我们通常叫做时间复杂度,可以使用大O表示法
  • 空间维度:是指执行当前算法所需要占用多少内存空间,我们通常叫做空间复杂度

因此我们判定一个算法的效率主要就是看他执行过程的时间复杂度和空间复杂度情况。然后时间和空间却是像鱼和熊掌,不可兼得。那么我们就需要从中去一个平衡点,或者直接用空间来换时间(毕竟当今技术发展情况空间很廉价)。

1. 时间复杂度

算法的时间复杂度,并不是用来实际计算算法执行时间的。我们可以通过两种方式来对算法的效率来进行计算或估算。

  • 事后统计方法:通过设计好的测试程序和数据,在执行不同算法时,利用计算机计时器进行时间的记录,最后将记录结果进行比较。
    这种方式显然是有大的缺陷的:
       1. 受不同机器性能影响,结果差异很大;
       2. 测试时,使用的数据规模不同,对结果的影响也会很大,算法A在数据规模小时效果不一定优于算法B,但在数据规模庞大时,可能会有很好的表现;
       3. 事先设定好的测试程序,对不同算法的性能不一定能达到最优表现;

  • 事前分析统计方法:在计算机程序编写前,依据统计方法对算法进行估算。(大O记法)
    抛开计算机硬件与软件有关的因素,算法的效率主要依赖于两点:
       1. 算法采用的策略、方案;
       2. 数据的输入规模(输入量);

时间复杂度计算方法

一般情况下,随着输入规模n的增大,T(n)增长最慢的算法为最优算法。
显然,由此算法时间复杂度的定义可知,我们的三个求和算法的时间复杂度分别为O(1),O(n),O(n²)。


算法时间复杂度

大O表示法

  1. 用常数1代替运行时间中的所有加法常数;O(5) ==> O(1)
  2. 修改后的函数中,只保留最高阶项;O(n² + n + 3) ==> O(n²)
  3. 去除最高阶项的系数;O(5n³ + 3n² +2) ==> O(n³)

常见的时间复杂度量级

  • 常数阶O(1):除去所有对算法结果本身无任何影响的操作,只针对算法实际有效项计算时间复杂度。
int sum = 0, n = 100;
printf("当前:"+sum+","+n);    //对算法结果无任何影响
sum = (1+n)*n/2;
  • 线性阶O(n):一般含有非嵌套循环涉及线性阶,线性阶就是随着问题规模n的扩大,对应计算次数呈直线增长。
int i , n = 100, sum = 0;
for( i=0; i < n; i++ )
{
    sum = sum + i;
}
  • 平方阶O(n²) / 立方阶O(n³):外层循环每执行一次,内层循环就执行100次,那总共程序想要从这两个循环出来,需要执行100*100次,也就是n的平方O(n²)
    如果有三个这样的嵌套循环也就是n的立方O(n³)
int i, j, n = 100;
for( i=0; i < n; i++ )
{
    for( j=0; j < n; j++ )
    {
        printf("i=" + i + ";j=" + j + ";n=" + n);
    }
}

推论: K次方阶O(n^k)

  • 对数阶O(logN):由于每次i*2之后,就距离n更近一步,假设有x个2相乘后大于或等于n,则会退出循环。
    于是由2^x = n得到x = log(2)n,所以这个循环的时间复杂度为O(logn)。
int i = 1, n = 100;
while( i < n )
{
    i = i * 2;
}
  • 线性对数阶O(nlogN):

  • 指数阶(2^n):

2. 空间复杂度

算法的空间复杂度,也并不是用来计算程序实际占用的空间的。
空间复杂度是对一个算法运行过程中临时占荣存储空间大小的一个度量,同样反映的是一个趋势,我们用S(n)来定义。

空间复杂度比较常用的有:O(1)、O(n)

  • O(1): 算法执行所需要的临时空间不随着某个变量n的大小而变化,即此算法空间复杂度为一个常量,可表示为 O(1)
int i = 1;
int j = 2;
++i;
j++;
int m = i + j;

代码中的 i、j、m 所分配的空间都不随着处理数据量变化,因此它的空间复杂度 S(n) = O(1)

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