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

山明水秀
• 阅读 1399

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

前言

本篇文章收录于专辑:http://dwz.win/HjK,点击解锁更多数据结构与算法的知识。

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

上一节,我们一起学习了表示复杂度的几个符号,我们说,通常使用大O来表示算法的复杂度,不仅合理,而且书写方便。

那么,使用大O表示法评估算法的复杂度有没有什么套路呢?以及常见的复杂度有哪些呢?

本节,我们就来解决这两个问题。

前情回顾

在正式讲解套路之前,我们先回忆一下前面几节讲到的内容。

在第2节,我们学习了渐近分析法,将算法的复杂度与输入规模挂钩,随着输入规模的增大,算法执行的时间将呈现一种什么样的趋势,将这个趋势用函数表示,再去除低阶项和常数项,就得到了算法的时间复杂度。

在第3节,我们分别从最坏、平均、最好三种情况来分析了算法的复杂度,得出结论,一般使用最坏情况来评估算法的复杂度。

在第4节,我们通过动态数组的插入元素及经典快速排序的时间复杂度,解释了有的时候不能使用最坏情况来评估算法的复杂度。

在第5节,我们从读音、数学、通俗理解三个方面分析了各种表示算法复杂度的符号,得出结论还是使用大O比较香,大O代表了算法的上界,它与前面讲到的最坏情况往往是对应的。

所以,这里所说的套路也是针对大部分情况,也就是最坏情况,对于一些个例,比如经典快排,我们虽然也是使用大O表示他们的复杂度,但是,其实是一种均摊的复杂度。

好了,让我们看看计算算法复杂度的套路到底是什么吧。

套路

我将计算算法复杂度的套路归纳为以下五步:

  1. 明确输入规模n;
  2. 考虑最坏情况或均摊情况,如果最坏情况为个例,那就是均摊;
  3. 计算算法执行的次数与n的关系,并用函数表示出来;
  4. 去除低阶项;
  5. 去除常数项;

比如,对于在数组中查找指定元素的操作:

  1. 输入规模为数组的长度n;
  2. 考虑最坏情况为目标元素不在数组中;
  3. 算法的执行次数为遍历所有数组元素,也就是n次,用函数表示f(n) = n;
  4. 去除低阶项,没有低阶项,还是n;
  5. 去除常数项,没有常数项,还是n;

所以,在数组中查找指定元素的时间复杂度为O(n)。

OK,使用这种方式可以很快的计算出算法的复杂度,也不需要进行额外的计算,非常快捷高效。

常见的复杂度

上面我们说了,复杂度的计算就是计算与输入规模n的关系,所以,我们想想数学中关于n的函数就能得出常见的复杂度了,我绘制了一张表格:

与n的关系 英文释义 复杂度 示例
常数(不相关) Constant O(1) 数组按索引查找元素
对数相关 Logarithmic O(logn) 二分查找
线性相关 Linear O(n) 遍历数组的元素
超线性相关 Superlinear O(nlogn) 归并排序、堆排序
多项式相关 Polynomial O(n^c) 冒泡排序、插入排序、选择排序
指数相关 Exponential O(c^n) 汉诺塔
阶乘相关 Factorial O(n!) 行列式展开
n的n次方 O(n^n) 不知道有没有这种算法

在这张表中,复杂度是依次增加的,可以看到常数复杂度O(1)无疑是最好的,让我们用一张图来直观感受下:

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

后记

本节,我们一起学习了复杂度分析的套路以及常见的复杂度,到目前为止,我们不管是举例还是讲解基本上都在说时间复杂度。

那么,空间复杂度又是什么呢?空间与时间之间如何权衡呢?

下一节,我们接着聊。

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

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

点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
美凌格栋栋酱 美凌格栋栋酱
6个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Wesley13 Wesley13
3年前
java小白到架构师技术图谱(整理全网,持续更新)
本文整理于github上各大star大神仓库。并根据自己的理解重新进行了整理本文已经收录于https://github.com/fengdongdongwsn/architectjava一、计算机基础1、数据结构(1)基本数据结构数据结构基本概念(时间复杂度和空间复杂度的计算方法)
似梦清欢 似梦清欢
2年前
链表题目解析
!image(https://imghelloworld.osscnbeijing.aliyuncs.com/imgs/22072c2df4aefa9a18649144a3d2eae4.png):::tip空间复杂度(Spac
梦
4年前
微信小程序new Date()转换时间异常问题
微信小程序苹果手机页面上显示时间异常,安卓机正常问题image(https://imghelloworld.osscnbeijing.aliyuncs.com/imgs/b691e1230e2f15efbd81fe11ef734d4f.png)错误代码vardate'2021030617:00:00'vardateT
Stella981 Stella981
3年前
SpringBoot整合Redis乱码原因及解决方案
问题描述:springboot使用springdataredis存储数据时乱码rediskey/value出现\\xAC\\xED\\x00\\x05t\\x00\\x05问题分析:查看RedisTemplate类!(https://oscimg.oschina.net/oscnet/0a85565fa
Easter79 Easter79
3年前
SpringBoot整合Redis乱码原因及解决方案
问题描述:springboot使用springdataredis存储数据时乱码rediskey/value出现\\xAC\\xED\\x00\\x05t\\x00\\x05问题分析:查看RedisTemplate类!(https://oscimg.oschina.net/oscnet/0a85565fa
Wesley13 Wesley13
3年前
2020年写的文章整理到了这里,请查收!
写在前面2020年默默地还是写了很多东西的,微信有了标签功能之后,整理起文章来还是比较方便的。从去年到今年准备写几个专辑,围绕于自己做交易系统或是一些通用解决方案的,当然自己平时爱叨叨的毛病也整理了一个专辑,回顾起来还比较有意思。复杂度治理系统变大之后,对应的复杂度就上来了,除了需要解决各种高性能、高可用、高并发的“规模
Stella981 Stella981
3年前
Linux应急响应(一):SSH暴力破解
0x00前言SSH是目前较可靠,专为远程登录会话和其他网络服务提供安全性的协议,主要用于给远程登录会话数据进行加密,保证数据传输的安全。SSH口令长度太短或者复杂度不够,如仅包含数字,或仅包含字母等,容易被攻击者破解,一旦被攻击者获取,可用来直接登录系统,控制服务器所有权限。0x01应急场景某天,网站
CRM从哪些方面进行了管理?
我们将CRM(https://www.sap.cn/products/crm.html!image(https://imghelloworld.osscnbeijing.aliyuncs.com/imgs/17e2d96568a98f0