算法笔记Day1 | 时间复杂度和空间复杂度的七七八八

news2024/9/26 1:27:49

文章目录

  • 时间空间复杂度
    • 1. 时间空间复杂度的重要性(作用)
    • 2. 时间复杂度和大O表示法
      • 1)算法图解
      • 2)代码随想录
      • 3)王道《数据结构》
    • 3. 大O指的是最糟的情形和一般的情形
      • 1)大O表示的是一般情况,并不是严格的上界
      • 2)王道中对三个维度的时间复杂度的解释:
    • 4. 常见的大O运行时间及化简规则
      • 1)常见渐进复杂度排序:
      • 2)分析程序复杂性,化简规则:
      • 3)大O可以省略常数项系数的原因
      • 4) 复杂度化简的例子
    • 5. 空间复杂度
      • 1)代码随想录
      • 2)王道数据结构
    • 6. O(logn)的解读

算法是一组完成任务的指令。任何代码片段都可视为算法。——《算法图解》

特别说明:文章是整理的笔记加自己汇集的资料及理解,参考自代码随想录、王道《数据结构》、《算法图解》(最近跟着carl哥准备刷题了,会坚持更新,争取早日养成输出的习惯)

时间空间复杂度

1. 时间空间复杂度的重要性(作用)

即使我们知道CPU运行一个程序所需的时间不只是算法执行的时间,比如

  • CPU执行每条指令所需的时间实际上并不相同,例如CPU执行加法和乘法操作的耗时实际上都是不一样的。
  • 现在大多计算机系统的内存管理都有缓存技术,所以频繁访问相同地址的数据和访问不相邻元素所需的时间也是不同的。
  • 计算机同时运行多个程序,每个程序里还有不同的进程线程在抢占资源。

尽管影响的因素甚多,但至少我们对自己写的程序的运行时间有个大体的评估。总不能写个查询人都反应过来了,程序还在执行中吧。

算法4中提到:

  • 火箭科学家需要大致知道一枚试射火箭的着陆点是在大海里还是在城市中;
  • 医学研究者需要知道一次药物测试是会杀死还是会治愈实验对象;

所以任何开发计算机程序员的软件工程师都应该能够估计这个程序的运行时间是一秒钟还是一年。

事实上抛开电脑的硬件配置,评估我们写的每一段程序好与差,最重要的还是时间和空间复杂度。 引用王道《数据结构》中的一句话,算法效率的度量是通过时间复杂度和空间复杂度来描述的。

2. 时间复杂度和大O表示法

先上结论,后边依次给出三个地方对时间复杂度的理解

  • 算法的速度指的并非时间,而是操作数的增速
  • 当讨论算法的速度时,我们说的是随着输入的增加,其运行时间将以什么样的速度增加
  • 算法的运行时间用大O表示法表示

1)算法图解

最喜欢《算法图解》中给出的解释:大O表示法指出算法的速度有多快,即大O表示法让你能够比较操作数,指出了算法运行时间的增速

即大O解决两个问题:一是估计当前问题规模n下的运行时间,二是估计出随问题规模n的增大,算法运行时间的增速的变化

举一个书中的列子:Bob为NASA编写一个查找算法,此算法在火箭即将登陆月球前执行,帮助计算登陆地点,时间需10秒内(简单算法和二分查找中选一个)。

测试时列表中有100个元素(假设查一个元素需1毫秒,默认有序),简单查找需100毫秒,二分查找需7毫秒。而实际中了包含10亿个元素,10亿元素查询时二分查找运行时间30毫秒(log2(1000000000)约为30)。

但Bob根据100个元素得出的结论,二分查找的速度约为简单查找的15倍,10亿个元素简单查找为30*15=450毫秒,同时简单查找编写简单bug率低,Bob毅然选择简单查询。

实际上,10亿量级时最坏时间复杂度需10亿毫秒(整整11天啊!)。

Bob会简单的认为二分查找的速度约为简单查找的15倍本质原因:评价算法时只用了运行时间来衡量,这是没有意义的。

同一个问题,用同一种算法,由于问题规模的不同,首先时间是不同的,重要的是时间的增长速度也不同。所以评价算法的快慢用时间衡量没有意义,选择将算法需要执行的操作次数表示为问题规模n的函数,既可以通过输入规模n得出运行时间,也可以通过分析函数表达式本身的性质发现运行时间增速的变化。

贴出简单查询和二分法的时间复杂度函数
在这里插入图片描述

2)代码随想录

时间复杂度是一个函数,它定性描述该算法的运行时间。

如何估算算法的运行时间?
通常估算算法的操作单元数量来代表程序消耗的时间(默认CPU的每个单元运行消耗的时间都相同)。

假设算法的问题规模为n,那么操作单元数量便用函数f(n)来表示,随着数据规模n的增大,算法执行时间的增长率和f(n)的增长率相同,这称作为算法的渐近时间复杂度,简称时间复杂度,记为 O(f(n))

3)王道《数据结构》

一个语句的频度是指该语句在算法中被重复执行的次数。而算法中所有语句的频度之和记作T(n),即该算法问题的规模n的函数

时间复杂度是分析T(n)函数的数量级,算法中的基本运算(最深层循环内的语句)的频度f(n)与T(n)同数量级,所以算法的时间复杂度记为:T(n) = O(f(n))(‘O’的含义是T(n)的数量级)

3. 大O指的是最糟的情形和一般的情形

1)大O表示的是一般情况,并不是严格的上界

算法导论给出的解释:大O用来表示上界的,当用它作为算法的最坏情况运行时间的上界,就是对任意数据输入的运行时间的上界。

算法图解中也有提到:大O说的是最糟的情形。

用算法导论中给出的例子:插入排序的时间复杂度我们通常都说是O(n^2) 。

输入数据的形式对程序运算时间是有很大影响的,在数据本来有序的情况下时间复杂度是O(n),但如果数据是逆序的话,插入排序的时间复杂度就是O(n^2) ,也就对于所有输入情况来说,最坏是O(n^2) 的时间复杂度,所以称插入排序的时间复杂度为O(n^2)。

同样的同理再看一下快速排序,都知道快速排序是O(nlogn),但是当数据已经有序情况下,快速排序的时间复杂度是O(n^2) 的。

所以严格从大O的定义来讲,快速排序的时间复杂度应该是O(n^2)。但是我们依然说快速排序是O(nlogn)的时间复杂度。

这个就是业内的一个默认规定,这里说的O代表的就是一般情况,而不是严格的上界。

2)王道中对三个维度的时间复杂度的解释:

最坏时间复杂度: 指最坏情况下,算法的时间复杂度
平均时间复杂度 指所有可能输入实例在等概率出现的情况下,算法的期望运行时间。
最好时间复杂度 指在最好情况下,算法的时间复杂度。

4. 常见的大O运行时间及化简规则

  • O(log2(n)): 也叫对数时间,算法包括二分查找。
  • O(n): 也叫线性时间,算法包括简单查找。
  • O(n*logn): 算法包括快速排序,速度比较快的排序。
  • O(n^2): 算法包括选择排序,速度比较慢的排序。
  • O(n!): 算法包括旅行商问题,一种非常慢的算法。

图片来自算法图解,方便理解增速
图片来自算法图解

1)常见渐进复杂度排序:

O(1)常数阶 < O(logn)对数阶 < O(n)线性阶 < O(nlogn)线性对数阶 < O(n^2)平方阶 < O(n^3)立方阶 < O(n!)n的阶乘 < O(2^n)指数阶

2)分析程序复杂性,化简规则:

1)加法规则
T(n) = T1(n) + T2(n) =O(f(n)) + O(g(n)) =O(max(f(n),g(n)))

2)乘法规则
T(n) = T1(n) * T2(n) = O(f(n)) * O(g(n)) = O(f(n) * g(n))

*注:化简例子在下一个大标题下

3)大O可以省略常数项系数的原因

附上代码随想录中的一个举例,如图是不同算法的时间复杂度在不同数据输入规模下的差异。
在这里插入图片描述
通常要决定使用哪种算法时,并不仅仅只考虑时间复杂度,也需要考虑数据规模。

如果数据规模很小甚至可以用O(n^2)的算法比O(n)的更合适(在有常数项的时候)。

比如上图中 O(5n^2) 和 O(100n) 在n为20之前很明显 O(5n^2)是更优的,所花费的时间也是最少的。

但O(100n) 就是O(n)的时间复杂度,O(5n^2) 就是O(n^2)的时间复杂度,为什么要默认O(n) 优于O(n^2) 呢?

这是因为大O就是数据量级突破一个点且数据量级非常大的情况下所表现出的时间复杂度,这个数据量也就是常数项系数已经不起决定性作用的数据量。

例如上图中20就是那个点,n只要大于20 常数项系数已经不起决定性作用了。

所以我们说的时间复杂度都是省略常数项系数的,是因为一般情况下都是默认数据规模足够的大, 基于这样的事实,给出的算法时间复杂的的一个排行如下所示:

O(1)常数阶 < O(logn)对数阶 < O(n)线性阶 < O(nlogn)线性对数阶 < O(n^2)平方阶 < O(n^3)立方阶 < O(n!)n的阶乘 < O(2^n)指数阶

但是也要注意大常数,如果这个常数非常大,例如10^7 ,10^9 ,那么常数就是不得不考虑的因素了。

4) 复杂度化简的例子

示例:O(2n^2 + 10n + 1000)

1)去掉运行时间中的加法常数项 (因为常数项并不会因为n的增大而增加计算机的操作次数)
O(2n^2 + 10n)

2)去掉常数系数(上文中已经详细讲过为什么可以去掉常数项的原因)
O(n^2 + n)

3)提取n的操作,变成O(n(n+1)) ,省略加法常数项后也就别变成了:
O(n^2)

5. 空间复杂度

1)代码随想录

定义: 空间复杂度(Space Complexity)记作S(n) 依然使用大O来表示,是对一个算法在运行过程中占用内存空间大小的量度,记做 S(n)=O(f(n))。

作用: 利用程序的空间复杂度,可以对程序运行中需要多少内存有个预先估计。

注意: 空间复杂度只是预先大体评估程序内存使用的大小,不能准确评估。毕竟很多因素会影响程序真正内存使用大小,例如编译器的内存对齐,编程语言容器的底层实现等等这些都会影响到程序内存的开销

空间复杂度O(1): 随n的变化,所需开辟的内存空间并不会随n的变化而变化。即此算法空间复杂度为一个常量,所以表示为O(1)。在王道数据结构中称此为算法原地工作(即指所需辅助空间是常量)

int j = 0;
for (int i = 0; i < n; i++) {
    j++;
}

空间复杂度为O(n): 当消耗空间和输入参数n保持线性增长,这样的空间复杂度为O(n)

int[] a = new int[n] //随着n的增大,开辟的内存大小呈线性增长,即 O(n)
for (int i = 0; i < n; i++) {
    a[i] = i;
}

2)王道数据结构

算法的空间复杂度S(n),定义为该算法所耗费的存储空间,它是问题规模n的函数。

渐进空间复杂度简称为空间复杂度。记作S(n) = O(g(n))。这里的g(n) 同代码随想录在空间复杂度给出的f(n)一样,都为程序语句关于n所占存储空间的函数。

6. O(logn)的解读

通常我们所说的算法的时间复杂度是logn不一定只是log 以2为底n的对数,可以是以10为底n的对数,也可以是以20为底n的对数,但我们统一说 logn,也就是忽略底数的描述。

如下图解释(图片截与代码随想录):
在这里插入图片描述
假如有两个算法的时间复杂度,分别是log以2为底n的对数和log以10为底n的对数,因为以2为底n的对数 = 以2为底10的对数 * 以10为底n的对数。(下方贴出了推到过程)

而以2为底10的对数是一个常数,在上文已经讲述了我们计算时间复杂度是忽略常数项系数的。

抽象一下就是在时间复杂度的计算过程中,log以i为底n的对数等于log 以j为底n的对数,所以忽略了i,直接说是logn。

这就是为什么时间复杂度logn可以忽略底数描述了。

补充解释第二个对数公式成立推导:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/504802.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

海量请求下,高并发接口的设计思路

1. 背 景 虽然现在很多人&#xff0c;动不动就提什么高并发、请求量多大&#xff0c;数据量多少多少&#xff0c;但我可以很认真地说&#xff0c;那都是他妈的在吹牛&#xff01; 生产环境&#xff0c;真正有大请求量的&#xff0c;就那么几个业务场景&#xff0c;而且多是面…

应急物流 | 灾后早期阶段多目标选址路径问题的混合元启发式算法

解读作者&#xff1a;李奡&#xff0c;闫同仁 A hybrid meta-heuristic algorithm for the multi-objective location-routing problem in the early post-disaster stage Tongren Yan, Fuqiang Lu, Suxin Wang, Leizhen Wang, Hualing Bi Journal of industrial and managem…

云原生应用架构

本博客地址&#xff1a;https://security.blog.csdn.net/article/details/130566883 一、什么是云原生应用架构 成为云原生应用至少需要满足下面几个特点&#xff1a; ● 使用微服务架构对业务进行拆分。单个微服务是个自治的服务领域&#xff0c;对这个领域内的业务实体能够…

Nature | 通用医学人工智能基础模型

编译 | 李汭璨 审稿 | 王建民 今天为大家介绍的是来自Eric J. Topol和 Pranav Rajpurkar研究团队的一篇医学人工智能的综述论文。高度灵活、可重复使用的人工智能模型的极快发展可能会为医学带来新的能力。作者提出了医学人工智能的新范式&#xff0c;称为通用医学人工智能&…

磁盘和文件系统管理

个人简介&#xff1a;云计算网络运维专业人员&#xff0c;了解运维知识&#xff0c;掌握TCP/IP协议&#xff0c;每天分享网络运维知识与技能。座右铭&#xff1a;海不辞水&#xff0c;故能成其大&#xff1b;山不辞石&#xff0c;故能成其高。个人主页&#xff1a;小李会科技的…

Deepnlp EquationGPT公式搜索引擎搜Latex源码和论文

公式搜索引擎常用功能 DeepNLP的EquationGPT用的比较多功能: 网址&#xff1a;EquationGPT Largest Equation Database & Engine powered by GPT 1. 公式搜索引擎&#xff0c;输入公式搜索数学公式的Latex代码和相应论文。 2. 目前覆盖了计算机(机器学习/AI)/ 数学/物理…

【设计模式】总结篇

【C语言部分】总结篇 【操作系统】总结篇 【数据库】总结篇 【计算机网络】总结篇 本文目录 1. 说说什么是单例设计模式&#xff0c;如何实现2. 简述一下单例设计模式的懒汉式和饿汉式&#xff0c;如何保证线程安全3. 说说工厂设计模式&#xff0c;如何实现&#xff0c;以及它的…

判断无穷积分是绝对收敛还是条件收敛---练习题

本篇文章重点讨论一般无穷积敛散性的判别。&#xff08;即被积函数在所积区间符号不定&#xff0c;既有正的&#xff0c;也有负的&#xff09; 不论是绝对收敛还是条件收敛&#xff0c;它本身一定是 收敛的。 狄利克雷判别法&#xff1a; 例题&#xff1a; 首先&#xff0c;将…

(4)Qt——基本组件

目录 1. Designer 设计师** 2. Layout 布局*** 3. 基本组件 3.1 QWidget** 3.2 ui指针 3.3 QLabel 标签** 3.4 QAbstractButton 按钮类** 3.5 QLineEdit 单行文本输入框** 3.6 QComboBox 组合框** 3.7 一组与数值相关的组件* 1. Designer 设计师** Designer是一款独立的用于设计…

【Java】进程通信(共享内存)

&#x1f388;博客主页&#xff1a;&#x1f308;我的主页&#x1f308; &#x1f388;欢迎点赞 &#x1f44d; 收藏 &#x1f31f;留言 &#x1f4dd; 欢迎讨论&#xff01;&#x1f44f; &#x1f388;本文由 【泠青沼~】 原创&#xff0c;首发于 CSDN&#x1f6a9;&#x1f…

PyQt5桌面应用开发(12):QFile与线程安全

本文目录 PyQt5桌面应用系列segment faultgdb backtraceopen & readQFile总结 PyQt5桌面应用系列 PyQt5桌面应用开发&#xff08;1&#xff09;&#xff1a;需求分析 PyQt5桌面应用开发&#xff08;2&#xff09;&#xff1a;事件循环 PyQt5桌面应用开发&#xff08;3&…

怎么恢复回收站?分享4个宝藏方法!

案例&#xff1a;怎么恢复回收站 【请问大家怎么恢复误删的文件呀&#xff1f;如果回收站被清空了&#xff0c;又应该怎么恢复呢&#xff1f;】 电脑回收站是我们存储被删除文件的地方。但是有时候&#xff0c;我们会不小心把一些重要的文件或者照片误删了。这时候&#xff0…

LED驱动程序框架

1. 字符设备驱动程序框架 2. 基于分层思想的LED驱动 2.1 把驱动拆分为通用的框架和具体的硬件操作 把驱动拆分为通用的框架(leddrv.c)、具体的硬件操作(board_X.c)&#xff1a; 如图&#xff1a; 以面向对象的思想&#xff0c;改进代码 抽象出一个结构体&#xff1a; 每个…

数据库管理-第七十三期 最近(20230509)

数据库管理 2023-05-09 第七十三期 最近1 证书2 EMCC 13.5.0.143 破百总结 第七十三期 最近 五一前后&#xff0c;除了X8那台的故障以外&#xff0c;还是做了或者探索了一些其他的东西。 1 证书 在五一假期的最后一天&#xff0c;还是在家通过线上的方式通过了1Z0-902&#…

Springboot +Flowable,三种常见网关的使用(排他、并行、包容网关)(一)

一.简介 Flowable 中常用的网关主要有三种类型&#xff0c;分别是&#xff1a; 排他网关并行网关包容网关 下面来说下这三种的网关的概念和用法。 二.排他网关 排他网关&#xff0c;也叫互斥网关&#xff0c;截图如下&#xff1a; 排他网关有一个入口&#xff0c;多个有效…

亚马逊云科技发力医疗与生命科学行业,加速数字化创新

2023年4月27日&#xff0c;亚马逊云科技医疗与生命科学行业峰会召开&#xff0c;会议汇聚了业界专家和思想领袖&#xff0c;共同探讨行业数字化转型和创新之道。作为全球医疗及生命科学行业云计算引领者&#xff0c;亚马逊云科技将围绕数据、算力和行业用户体验三大需求发力&am…

MySQL百万数据深度分页优化思路分析

业务场景 一般在项目开发中会有很多的统计数据需要进行上报分析&#xff0c;一般在分析过后会在后台展示出来给运营和产品进行分页查看&#xff0c;最常见的一种就是根据日期进行筛选。这种统计数据随着时间的推移数据量会慢慢的变大&#xff0c;达到百万、千万条数据只是时间…

UWA发布 | Unity手游性能蓝皮书

最新2022年度Unity手游蓝皮书出炉&#xff01;此次发布分析了2022年1月至2023年3月期间&#xff0c;游戏行业使用Unity引擎进行手游开发过程中及游戏上线后的性能表现&#xff0c;从测试机型分布、引擎各模块开销、内存占用等方面进行汇总分析&#xff0c;反映了Unity手游行业的…

Flink dataStream,如何开窗,如何进行窗口内计算

目录 开窗方式 windowAll() window() 窗口类型 基于时间 基于数量 开窗后的处理函数 全量聚合函数&#xff08;也叫窗口函数&#xff09; 增量聚合函数 增量聚合函数携带一个全量聚合函数 开窗方式 windowAll() 对于没有keyBy的数据流 window() 对于KeyBy后的数据…

交工技术文档表格-SH3503-2001

(阀门试验记录)(管道补偿器安装记录)(管道组成件校验性检查记录)(SHA级管道管螺纹、密封面加工记录)(高压、SHA级管道弯管加工记录)(管道静电接地测试记录)管道系统安装检查与压力试验记录)管道系统泄露性与真空试验记录)(管道吹洗、清洗脱脂记录)(给排水压力管道强度及严密试验…