前一篇文章算法复杂度分析(上)讲述了复杂度的大 O 表示法和几个分析原则,这篇文章我们来讲讲另外几种复杂度,最好情况时间复杂度(best case time complexity)、最坏情况时间复杂度(worst case time complexity)、平均时间复杂度(average case time complexity)和均摊时间复杂度(amortized time complexity)。

最好、最坏情况时间复杂度

顾名思义,这两种时间复杂度指的是特殊情况下的时间复杂度。我们看下面的例子:

// n 表示数组 array 的长度
int find(int[] array, int n, int x) {int i = 0;int pos = -1;for (; i < n; ++i) {if (array[i] == x) {pos = i;break;}}return pos;
}
复制代码

这段代码实现的功能是,在数组 array 中寻找变量 x 第一次出现的位置,若没有找到,则返回 -1;否则返回位置下标。

用上一篇文章的方法显然是无法分析这段代码的复杂度的。因为,不同情况下的时间复杂度是不同的。当数组中第一个元素就是要找的 x 时,时间复杂度是 O(1);而当最后一个元素才是 x 时,时间复杂度则是 O(n)。

为了表示代码在不同情况下的时间复杂度,就需要引入三个概念:最好情况时间复杂度、最坏情况时间复杂度和平均情况时间复杂度。

其中,最好情况时间复杂度就是在最理想情况下执行代码的时间复杂度,它的时间是最短的;最坏情况时间复杂度就是在最糟糕情况下执行代码的时间复杂度,它的时间是最长的。

平均情况时间复杂度

最好、最坏时间复杂度反应的是极端条件下的复杂度,发生的概率不大,不能代表平均水平。那么为了更好的表示平均情况下的算法复杂度,就需要引入平均时间复杂度。

继续用前面 find 函数为例,假设变量 x 在和不在数组 array 中的概率分别为 1 / 2;当存在于数组中时,在每个位置的概率均等,为 1 / n。那么,平均情况时间复杂度就可以用下面的方式计算:

((1 + 2 + ... + n) / n + n) / 2 = (3n + 1) / 4

这个值就是概率论中的加权平均值,也叫期望值。所以平均情况时间复杂度也叫加权平均时间复杂度或期望时间复杂度。可见,find 函数的平均时间复杂度为 O(n)。

大多数情况下,不需要区分最好、最坏、平均情况时间复杂度,只用一个复杂度就可以满足需求了。只有当同一块代码在不同情况下,时间复杂度有数量级上的区别时,才需要考虑这三种复杂度。

均摊时间复杂度

由上面我们可以知道,平均时间复杂度只有在某些特殊的时候才会用到。均摊时间复杂度的应用场景比它更为特殊。均摊时间复杂度是指,当大部分情况下时间复杂度都很低,只有个别情况下时间复杂度比较高时,并且这些操作之间存在着前后连贯的时序关系,这时候,可以将较高时间复杂度的操作耗时均摊至时间复杂度较低的操作上。这种分析方法叫做摊还分析法,得到的复杂度叫做均摊时间复杂度。

而且,在能够应用均摊时间复杂度分析的场合,一般均摊时间复杂度就等于最好情况时间复杂度。

例如:

int[] array = new int(n);
int count = 0;void addLast (int val) {if (count == array.length) {int[] newArray = new int(2 * n);for (int i = 0; i < 2 * n; i++) {newArray[i] = array[i];}newArray[count] = val;array = newArray;} else {array[count] = val}count++;
}
复制代码

这段代码实现的功能是往数组的末尾增加一个元素,如果数组没有满,直接往后面插入元素;如果数组满了,即 count == array.length,则将数组扩容一倍,然后再插入元素。

例如,数组长度为 n,则前 n 次调用 addLast() 复杂度都为 O(1);第 n + 1 次则需要先进行 n 次元素转移操作,然后再进行 1 次插入操作,复杂度为 O(n)。而且很容易看出,O(1) 复杂度的操作和 O(n) 复杂度的操作出现频率是有规律的,每 n 次 O(1) 操作后会跟随一个 O(n) 操作。

那么,就可以将 O(n) 操作的复杂度均摊至每次 O(1) 操作中,均摊下来,这组操作的需要进行 (n + n * 1) / (n + 1) = 2n / (n + 1) 次操作,所以均摊复杂度为 O(1)。


本文首发自微信公众号《代码写完了》

算法复杂度分析(下)相关推荐

  1. 八大排序:Java实现八大排序及算法复杂度分析

    目录 QUESTION:八大排序:Java实现八大排序及算法复杂度分析 ANSWER: 一:冒泡排序 1.算法分析 2.时间复杂度分析 3.代码 二:选择排序 1.算法分析 2.时间复杂度分析 3.代 ...

  2. 网络流问题以及EK算法复杂度分析

    网络流问题以及EK算法复杂度分析 一.网络流算法 通过一个例子引入网络流问题. 现有一个自来水厂要往家里通水,自来水厂用Vs表示,家用Vt表示.从自来水厂到家之间连接了很多水管,并且中途经过很多转接点 ...

  3. 算法复杂度分析看这一篇就够了

    执行效率是算法一个非常重要的考量指标,而时间复杂度和空间复杂度则是衡量算法代码的执行效率. 为什么需要复杂度分析 通常情况下,我们可以在写完代码的情况下把程序跑一遍,通过统计.监控,就能得出算法执行的 ...

  4. 算法复杂度分析(下):最好、最坏、平均、均摊等时间复杂度概述

    细化时间复杂度分析 代码千千万,有些代码逻辑会很复杂,所以为了更细化的分析算法的复杂度,再复杂度分析方面引入了4个知识点: 1.最好情况时间复杂度(best case time complexity) ...

  5. 第3课:算法复杂度分析(下):最好、最坏、平均、均摊时间复杂度

    目录 最好.最坏时间复杂度 平均情况时间复杂度 均摊时间复杂度 小结 最好.最坏时间复杂度 我们先看一个例子: /*例1:查找x在数组中出现的位置,如果没有找到,返回-1.n表示数组array的长度 ...

  6. 算法之如何进行算法复杂度分析

    一.什么是复杂度分析? 1.数据结构和算法解决是"如何让计算机更快时间.更省空间的解决问题". 2.因此需从执行时间和占用空间两个维度来评估数据结构和算法的性能. 3.分别用时间复 ...

  7. 怎么算matlab算法复杂度,算法复杂度分析

    1. 何为数据结构?何为算法? 简单来说,数据结构就是数据的存储方式,比如数组就是把数据存在一段连续的内存上,而链表则是通过指针的关联将数据存在任意可用的内存上:栈是先进后出,队列是先进先出. 而算法 ...

  8. 【排序综合】直接插入排序,希尔排序,快速排序,堆排序,冒泡排序,简单选择排序的简介,实现和算法复杂度分析

    目录 1. 直接插入排序 1.1 直接插入排序简介 1. 什么是直接插入排序 2. 排序思想 1.2 排序实现 1. 排序代码 2. 复杂度分析: 3. 运行结果: 1.3 学习链接 2. 希尔排序( ...

  9. 算法复杂度分析(3600字)

    文章目录 前言 一.复杂度分析的意义 二.复杂度分析基础 1. 大 O O O复杂度表示法 2. 时间复杂度分析方法 2.1 加法法则 2.2 乘法法则 3. 空间复杂度 总结 1. O ( 1 ) ...

最新文章

  1. wrs-arcface虹软人脸识别
  2. UI设计培训技术分享:配色秘籍
  3. QPS和并发数,这次给你说清楚
  4. 单手也能创奇迹!独臂博士单手敲代码获奖 30 余项:感恩所有的善意
  5. 学生上课考勤系统jsp_基于jsp的学生课堂考勤-JavaEE实现学生课堂考勤 - java项目源码...
  6. 一些PHP性能优化汇总
  7. Linux环境下服务器 Tomcat war包部署步骤
  8. android上传图片文件至c 服务器,Android 史上最优雅的实现文件上传、下载及进度的监听...
  9. 啪啪三国2获取服务器信息,啪啪三国2怎么快速的获得资源?
  10. 002.操作系统的选择
  11. python语言是二进制语言吗_在大型项目上,Python 是个烂语言吗?
  12. 苹果手机越狱后cydia的问题Could not open file - open
  13. ST语言和C语言的区别 STC
  14. vue-oss阿里云上传图片
  15. 最新微信域名防封_微信二级不死域名真的不死吗
  16. 安装windows XP或者2003时提示找不到硬盘驱动器的解决办法(总结)转载
  17. C Sleepy Kaguya
  18. JSP中response.sendRedirect()与request.getRequestDispatcher().forward(request,respon 区别
  19. ppt给图片增加高斯模糊_PPT图片处理小技巧
  20. win10 mmdetection3d 训练KITTI

热门文章

  1. 就业局培训计算机心得,人社局计算机培训心得体会.doc
  2. Java网络编程3---Socket-UDP编程
  3. 海浪 shader_海浪下的发现
  4. 我是一个喜欢桌游的前端女,跟朋友一起做了个桌游交流系统。在自己的系统里直播开发生活,希望得到更多交流...
  5. 制造领域的人工智能技术
  6. 『流畅的Python』第1~4章笔记_数据结构、编码
  7. 小到年货大到产业,刘村长的扶贫模式有点厉害!
  8. 苹果iOS 10.3.1修复博通Wi-Fi芯片重大安全漏洞
  9. gradle 转 maven
  10. 数据源的配置和使用 视频下载