算法时空复杂度分析:大O表示法

2024-03-14 17:44

本文主要是介绍算法时空复杂度分析:大O表示法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 前言
  • 大O表示法
  • 3个时间复杂度分析原则
  • 常见的时间复杂度量级
  • 空间复杂度
  • 参考资料

前言

算法题写完以后,面试官经常会追问一下你这个算法的时空复杂度是多少?(好像作为一名算法工程师,我日常码代码的过程中,并没有太注意这个,惭愧~但是找做后端开发的男票求证了一下,他们日常工作确实会去考虑这种问题)那么无论是为了应付面试,还是为了未来码代码可以精益求精,都还是认真的学一下时空复杂度分析方法吧!

对于为什么需要时空复杂度分析,而不是直接跑一下代码看看,看到王争大佬在《数据结构与算法之美》(墙推)里给的两个原因是:

  1. 测试结果依赖测试环境:机器的配置会十分影响你跑出的结果;
  2. 测试结果依赖数据规模的大小。

因此,我们需要一个不依赖数据规模和测试环境,帮助粗略估计算法执行效率的方法!也就是下面的大O表示法~

大O表示法

举个栗子🌰,下面这个函数的总的执行时间 T ( n ) = 1 + 2 n T(n) = 1+2n T(n)=1+2n个unit time!

def f(n: int)a = 0  # 1个unit timefor i in range(n):  # n个unit timea += i  # n个unit timereturn a

再举个栗子🌰,下面这个函数的总的执行时间 T ( n ) = 1 + n + 2 n 2 T(n) = 1+n+2n^2 T(n)=1+n+2n2个unit time!

def g(n: int, m: int)a = 0  # 1个unit timefor i in range(n):  # n个unit timefor j in range(n): # n^2个unit timea += i*j  # n^2个unit timereturn a

用一个公式表示就是:
在这里插入图片描述
其中:

  • T ( n ) T(n) T(n)表示代码执行的时间;
  • n n n:表示数据规模的大小;
  • f ( n ) f(n) f(n):表示每行代码执行的次数总和
  • O O O:表示执行时间 T ( n ) T(n) T(n) f ( n ) f(n) f(n)成正比。

所以第一个例子的时间复杂度为 T ( n ) = 1 + 2 n T(n) = 1+2n T(n)=1+2n,第二个例子的时间复杂度为 T ( n ) = 1 + n + 2 n 2 T(n) = 1+n+2n^2 T(n)=1+n+2n2,这就是大O时间复杂度表示法。大O时间复杂度表示法实际上并不是具体值代码执行的时间,而是代表代码执行时间随着数据规模增长的变化趋势,所以也叫渐进时间复杂度,简称时间复杂度。

当n很大时,公式中的低阶、常量、系数三部分并不左右增长趋势,所以都可以忽略,只需要记录一个最大量级即可!因此,上例的时间复杂度可以记为: T ( n ) = O ( n ) T(n) = O(n) T(n)=O(n) T ( n ) = O ( n 2 ) T(n) = O(n^2) T(n)=O(n2)

3个时间复杂度分析原则

3个原则:

1. 只关注循环执行次数最多的一段代码:
还是上面第一个例子,关注for循环这段代码就行了,a = 0这类代码都是常量级的执行时间,与 n n n无关。

def f(n: int)a = 0  # 1个unit timefor i in range(n):  # n个unit timea += i  # n个unit timereturn a

2. 总复杂度 = 量级最大的那段代码的复杂度:
这个有点像运筹学里关键路径法的思想,只有找到了最关键/量级最大的,你去优化的时候才能发力在刀刃上~

比如下面这段代码,有一层for循环的,有两层for循环,我们去关注两层for循环的这段代码即可。

def g(n: int, m: int)for i in range(n):passa = 0  # 1个unit timefor i in range(n):  # n个unit timefor j in range(n): # n^2个unit timea += i*j  # n^2个unit timereturn a

3. 嵌套代码的复杂度 = 嵌套内外代码复杂度的乘积:
上面的第二个例子,两层for循环嵌套,最后的时间复杂度 = 外层for循环的复杂度乘以里面for循环的复杂度。

def g(n: int, m: int)a = 0  # 1个unit timefor i in range(n):  # n个unit timefor j in range(n): # n^2个unit timea += i*j  # n^2个unit timereturn a

常见的时间复杂度量级

  • 多项式量级:下图左侧;
  • 非多项式量级:下图右侧波浪线。执行时间会随着数据规模的增大而急剧增大,是非常低效的算法

在这里插入图片描述
在这里插入图片描述

空间复杂度

又称为渐进空间复杂度,表示算法的存储空间与数据规模之间的增长关系!

举个栗子🌰,空间复杂度为 O ( n ) O(n) O(n)

def f(n: int):a = 2  # 1个空间存储变量,常量b = [] # 从下面代码可以看出时一个大小为n的数组for i in range(n):b.append(i)return b

参考资料

  1. 《数据结构与算法之美》王争

这篇关于算法时空复杂度分析:大O表示法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/809192

相关文章

Springboot中分析SQL性能的两种方式详解

《Springboot中分析SQL性能的两种方式详解》文章介绍了SQL性能分析的两种方式:MyBatis-Plus性能分析插件和p6spy框架,MyBatis-Plus插件配置简单,适用于开发和测试环... 目录SQL性能分析的两种方式:功能介绍实现方式:实现步骤:SQL性能分析的两种方式:功能介绍记录

最长公共子序列问题的深度分析与Java实现方式

《最长公共子序列问题的深度分析与Java实现方式》本文详细介绍了最长公共子序列(LCS)问题,包括其概念、暴力解法、动态规划解法,并提供了Java代码实现,暴力解法虽然简单,但在大数据处理中效率较低,... 目录最长公共子序列问题概述问题理解与示例分析暴力解法思路与示例代码动态规划解法DP 表的构建与意义动

C#使用DeepSeek API实现自然语言处理,文本分类和情感分析

《C#使用DeepSeekAPI实现自然语言处理,文本分类和情感分析》在C#中使用DeepSeekAPI可以实现多种功能,例如自然语言处理、文本分类、情感分析等,本文主要为大家介绍了具体实现步骤,... 目录准备工作文本生成文本分类问答系统代码生成翻译功能文本摘要文本校对图像描述生成总结在C#中使用Deep

Redis主从/哨兵机制原理分析

《Redis主从/哨兵机制原理分析》本文介绍了Redis的主从复制和哨兵机制,主从复制实现了数据的热备份和负载均衡,而哨兵机制可以监控Redis集群,实现自动故障转移,哨兵机制通过监控、下线、选举和故... 目录一、主从复制1.1 什么是主从复制1.2 主从复制的作用1.3 主从复制原理1.3.1 全量复制

Python中的随机森林算法与实战

《Python中的随机森林算法与实战》本文详细介绍了随机森林算法,包括其原理、实现步骤、分类和回归案例,并讨论了其优点和缺点,通过面向对象编程实现了一个简单的随机森林模型,并应用于鸢尾花分类和波士顿房... 目录1、随机森林算法概述2、随机森林的原理3、实现步骤4、分类案例:使用随机森林预测鸢尾花品种4.1

Redis主从复制的原理分析

《Redis主从复制的原理分析》Redis主从复制通过将数据镜像到多个从节点,实现高可用性和扩展性,主从复制包括初次全量同步和增量同步两个阶段,为优化复制性能,可以采用AOF持久化、调整复制超时时间、... 目录Redis主从复制的原理主从复制概述配置主从复制数据同步过程复制一致性与延迟故障转移机制监控与维

Redis连接失败:客户端IP不在白名单中的问题分析与解决方案

《Redis连接失败:客户端IP不在白名单中的问题分析与解决方案》在现代分布式系统中,Redis作为一种高性能的内存数据库,被广泛应用于缓存、消息队列、会话存储等场景,然而,在实际使用过程中,我们可能... 目录一、问题背景二、错误分析1. 错误信息解读2. 根本原因三、解决方案1. 将客户端IP添加到Re

Redis主从复制实现原理分析

《Redis主从复制实现原理分析》Redis主从复制通过Sync和CommandPropagate阶段实现数据同步,2.8版本后引入Psync指令,根据复制偏移量进行全量或部分同步,优化了数据传输效率... 目录Redis主DodMIK从复制实现原理实现原理Psync: 2.8版本后总结Redis主从复制实

锐捷和腾达哪个好? 两个品牌路由器对比分析

《锐捷和腾达哪个好?两个品牌路由器对比分析》在选择路由器时,Tenda和锐捷都是备受关注的品牌,各自有独特的产品特点和市场定位,选择哪个品牌的路由器更合适,实际上取决于你的具体需求和使用场景,我们从... 在选购路由器时,锐捷和腾达都是市场上备受关注的品牌,但它们的定位和特点却有所不同。锐捷更偏向企业级和专

Spring中Bean有关NullPointerException异常的原因分析

《Spring中Bean有关NullPointerException异常的原因分析》在Spring中使用@Autowired注解注入的bean不能在静态上下文中访问,否则会导致NullPointerE... 目录Spring中Bean有关NullPointerException异常的原因问题描述解决方案总结