如何进行算法的复杂度分析?

前言

本篇文章收录于专辑:http://dwz.win/HjK

你好,我是彤哥,一个每天爬二十六层楼还不忘读源码的硬核男人。

大家都知道,数据结构与算法解决的主要问题就是“快”和“省”的问题,即如何让代码运行得更快, 如何让代码更节省存储空间。

所以,“快”和“省”是衡量一个算法非常重要的两项指标,也就是我们经常听到的时间复杂度和空间复杂度分析。

那么,为什么需要复杂度分析呢?复杂度分析的方法论是什么呢?

这就是我们本节要解决的问题。

好了,进入今天的学习吧。

为什么需要复杂度分析?

首先,我们来思考一个问题:对于两个算法,我们如何评判谁运行得更快,谁运行时更节省内存?

你可能会说,这还不简单,把这两个算法运行一遍,统计下运行时间和占用内存不就可以了吗?

没错,这确实是一种不错的方法,而且它还有个非常形象的名字:事后统计法

但是,这种统计方法具有非常明显的问题:

  1. 不同的输入对结果影响很大

    对于一些输入,可能算法A执行得更快;对于另外一些输入,可能算法B执行得更快。比如,我们后面要学习的排序算法,输入的有序性对于不同的排序算法的影响是完全不同的。

  2. 不同的机器对结果影响很大

    对于同样的输入,可能在一台机器上算法A更快,而在另外一台机器上算法B更快。比如,算法A可以利用多核而算法B不能,那么CPU的核数对这两个算法的影响将截然不同。

  3. 数据规模对结果影响很大

    当数据规模小时,可能算法A更快,而数据规模变大时,可能算法B更快。比如,我们后面要学习的排序算法,当数据规模比较小时,插入排序反而比归并排序更快。

所以,我们需要一种可以不用实际运行算法,就可以估计算法执行效率的方法。

这也就是我们所说的复杂度分析。

那么,怎么进行复杂度分析呢?有没有什么方法论呢?

还真有,这个方法论叫作渐近分析法

什么是渐近分析法?

渐近分析法,是指将算法执行的效率与输入的规模进行挂钩,随着输入规模的增大,算法执行所需要的时间(或空间)将呈现一种什么样的趋势,这种趋势就叫作渐近,而这种方法就叫作渐近分析法

概念可能比较拗口,我举个简单的例子,对于给定的一个有序数组,我要查找其中某个值所在的位置,比如,查找8这个元素,有哪些方法呢?

简单暴力点的方法,从头遍历,查找到该元素即返回。

更友好一点的方法,采用二分法,每次定位到数据的中间位置,看其值与目标值的大小,判断是在左边还是右边继续以二分的方式查找。

上面我们举的例子的输入规模是8个元素的有序数组,目标值为8,使用第二种方法明显比第一种方法要快很多。

但是,如果查找的目标是1呢?

对于第一种方法,查找一次足矣。

对于第二种方法,需要查找3次。

此时,第二种方法又次于第一种方法了。

所以,比较两个算法的执行效率,不能只考虑到个别元素,而应该顾及到所有元素的感受。

我们以数学的方法来统计两种方法的平均执行效率,假设输入规模扩展到n。

对于第一种方法,1号元素查找一次,2号元素查找两次,3号元素查找三次……,而查找每个元素的概率都是1/n。

所以,它的执行效率为:1x1/n + 2x1/n + 3x1/n + ... nx1/n = nx(n+1)/2/n = (n+1)/2。

对于第二种方法,中间的元素有一个,查找一次,次中间的元素有两个,查找两次,次次中间的元素有四个,查找三次...,每次查找的规模都缩小一半,而查找每个元素的概率都是1/n。

所以,它的执行效率为:1x1x1/n + 2x2x1/n + 4x3x1/n + ... + 2^(log2(n)-2) x (log2(n)-1) x 1/n+ 2^(log2(n)-1) x log2(n) x 1/n = ?

我了个去,这个结果等于多少?

是时候展现真正的实力了:

你可能要骂娘了,对于我一个小学毕业的,难道我没办法学习数据结构与算法了?

No,No,No,肯定不能这么玩,那么,应该怎么玩呢?我们下一节接着讲。

后记

本节,我们从算法执行效率方面阐述了为什么需要复杂度分析,并介绍了复杂度分析的方法,即渐近分析法,如果严格地遵循渐近分析法,需要大量的数学知识,这无疑增加了我们分析算法的难度,那么,有没有什么更省心地计算复杂度的方法呢?

关注公众号“彤哥读源码”,解锁更多源码、基础、架构知识!

(0)

相关推荐

  • 趣说:如何对代码进行复杂度分析

    你在学习数据结构算法的时候 你的目的就是为了让代码 运行的速度更加 "快" 占用的空间更加 "少" 那么当你看到一段代码的时候 你应该如何去分析它的运行效率? ...

  • 复杂度分析的套路及常见的复杂度

    前言 本篇文章收录于专辑:http://dwz.win/HjK,点击解锁更多数据结构与算法的知识. 你好,我是彤哥,一个每天爬二十六层楼还不忘读源码的硬核男人. 上一节,我们一起学习了表示复杂度的几个 ...

  • 复杂度分析和大O表示法

    学习数据结构和算法要从复杂度分析说起.表示时间的大O符号,是用来描述算法效率的语言和度量单位.算法复杂度包括时间复杂度和空间复杂度,两者中又以时间复杂度相对重要,因为就 Web 应用而言,我们常见的性 ...

  • 算法复杂度分析

    算法复杂度分析

  • 综述 | npj Biofilms and Microbiomes:微生物成分分析:标准化和差异丰度分析

    编译:独世,编辑:小菌菌.江舜尧. 原创微文,欢迎转发转载. 导读 越来越多研究表明微生物组与多种人类疾病之间存在一定的关联,例如肥胖.炎症性肠病.HIV等.进行微生物组广泛关联研究的第一步是在不同条 ...

  • 在外地上学回北京高考难易度分析

    北京高考的考题思路相较于外地有许多不同,但不能说北京高考就比外地容易.事实上,北京只是升学率更高,因为本地大学会赋予本地考生更多名额.建议回京高考要选择一所认真,负责的学校,这样才能令考生更快适应北京 ...

  • “遥感大数据+AI算法”赋能空间监测分析与城市体检研究|清华同衡

    作者 │ 张茜 如何进一步提高城市体检中空间指标的可评估性.精准性与客观性?2020年11月北京市规划和自然资源委员会数据管理中心数据创新发展科张茜科长在清华同衡第八届学术周上作了题为<遥感AI ...

  • 递归算法复杂度Ω分析-分享

    递归算法复杂度Ω分析-分享

  • 深度学习模型复杂度分析

    Transformer self-attention和position-wise FFN作为Transformer比较特殊的模块,这里只分析一下它们的复杂度,注意:这里的复杂度既包含时间,也包含空间. ...

  • QIIME 2教程. 08差异丰度分析gneiss(2020.11)

    QIIME 2用户文档. 8差异丰度分析gneiss Differential abundance analysis with gneiss 原文地址:https://docs.qiime2.org/ ...