算法时空复杂度分析:大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 time
	for i in range(n):  # n个unit time
		a += i  # n个unit time
	return 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 time
	for i in range(n):  # n个unit time
		for j in range(n): # n^2个unit time
			a += i*j  # n^2个unit time
	return 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 time
	for i in range(n):  # n个unit time
		a += i  # n个unit time
	return a

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

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

def g(n: int, m: int)
   for i in range(n):
   		pass
   		 
   a = 0  # 1个unit time
   for i in range(n):  # n个unit time
   	for j in range(n): # n^2个unit time
   		a += i*j  # n^2个unit time
   return a

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

def g(n: int, m: int)
	a = 0  # 1个unit time
	for i in range(n):  # n个unit time
		for j in range(n): # n^2个unit time
			a += i*j  # n^2个unit time
	return 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. 《数据结构与算法之美》王争

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

FreMIM:傅里叶变换与遮罩的图像建模在医学图像分割中的应用

代码链接:GitHub - Rubics-Xuan/FreMIM: This repo holds the official code for the paper "FreMIM: Fourier Transform Meets Masked Image Modeling for Medical Image Segmentation". 论文链接:https://arxiv.org/abs/2304.10864 收录于…

C#重新认识笔记_ FixUpdate + Update

C#重新认识笔记_ FixUpdate Update Update: 刷新频率不一致,非物理对象的移动,简单的刷新可用, FixedUpdate: 刷新频率一致,按照固定频率刷新,一般调用FixedUpdate之后,会立即进入必要的物理计算中,因此,任何影响刚…

springboot3 打包报错32-bit architecture x86 unsupported或者 returned non-zero result

springboot3 打包异常情况处理记录 在测试springboot3 native打包时候遇到的异常,百度和谷歌上方法都无法解决我的问题,最后记录一下我最后的原因和解决方案。 前置要求:自己处理好vs的相关内容后 报错一: [1/7] Initializing…

回归测试,有什么高效的测试方法?

什么是回归测试? 回归测试(Regression testing) 指在发生修改之后重新测试先前的测试以保证修改的正确性。理论上,软件产生新版本,都需要进行回归测试,验证以前发现和修复的错误是否在新软件版本上再次出现…

跨境电子商务支付与结算的支撑系统

​1、跨境电子商务支付与结算的核心系统。 核心系统是用户执行跨境电子商务支付的核心模块,包括以下具体流程。 ​ ​①用户从跨境电子商务支付应用启动跨境电子商务支付流程。 ②跨境电子商务支付应用根据应用和用户选择的支付工具,来调用对应的支付产…

来吧伙计们,让AI教我们怎么说海盗语

“如果想伺机而动,就是这样。”——杰克船长提到海盗,我们往往联想到约翰尼德普在《加勒比海盗》中饰演的杰克船长。我们有什么理由不喜欢海盗呢?他们航行在海上,寻找埋藏的宝藏,痛饮朗姆酒,用自己独特的海…

24考研调剂 | 武汉纺织大学

教育部重点实验室招收24年调剂生,材料、化学、机械工程、计算机、力学等相关专业 考研调剂招生信息 学校:武汉纺织大学 专业:工学->材料科学与工程 年级:2024 招生人数:100 招生状态:正在招生中 联系方式:********* (为保护个人隐私,联系方式仅限APP查看)…

springboot的maven多模块如何混淆jar包

springboot的maven多模块如何混淆jar包 一.简介二. 示例2.1 基本配置2.2 结果 三. 错误3.1 错误13.2 错误2 四. 参考文章 前言 这是我在这个网站整理的笔记,有错误的地方请指出,关注我,接下来还会持续更新。 作者:神的孩子都在歌唱 一.简介 …

王道机试C++第6章 数学问题和22年蓝桥杯省赛选择题Day34

6.1 进制转换 二进制数(十转二) 习题描述 大家都知道,数据在计算机里中存储是以二进制的形式存储的。 有一天,小明学了C语言之后,他想知道一个类型为unsigned int 类型的数字,存储在计算机中的二进制串是…

个人博客系统(测试报告)

一、项目背景 一个Web网站程序,你可以观看到其他用户博客也可以登录自己的账号发布博客,通过使用Selenium定位web元素、操作测试对象等方法来对个人博客系统的进行测试,测试的核心内容有用户登录、博客列表及博客数量的展示、查看全文、写博客…

Vue-Vben-Admin:中大型项目后台解决方案及如何实现页面反向传值

Vue-Vben-Admin:中大型项目后台解决方案及如何实现页面反向传值 摘要: Vue-Vben-Admin是一个基于Vue3.0、Vite、Ant-Design-Vue和TypeScript的开源项目,旨在为开发中大型项目提供一站式的解决方案。它涵盖了组件封装、实用工具、钩子函数、动…

Python逆向:pyc字节码转py文件

一、 工具准备 反编译工具:pycdc.exe 十六进制编辑器:010editor 二、字节码文件转换 在CTF中,有时候会得到一串十六进制文件,通过010editor使用查看后,怀疑可能是python的字节码文件。 三、逆向反编译 将010editor得到…

链路聚合实验(思科)

华为设备参考: 一,技术简介 网络设备的链路聚合技术(Link Aggregation)是一种将多个物理链路捆绑在一起,形成一个逻辑链路的技术。这样做可以增加带宽、提高可靠性和实现负载均衡。 二,实验目的 橙色的阻…

使用Sourcetree推送本地仓库至远程仓库时报错The host key is not cached for this server

原因是SSH没配置好 点击工具→选项→ 改成OpenSSH,密钥改成配置Git和本地仓库时生成的.ssh文件夹下的id_rsa文件。

Spring boot 集成netty实现websocket通信

一、netty介绍 Netty 是一个基于NIO的客户、服务器端的编程框架,使用Netty 可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户、服务端应用。Netty相当于简化和流线化了网络应用的编程开发过程,例如:基于TCP和U…

力扣-[700. 二叉搜索树中的搜索]

递归法 确定递归函数的参数和返回值 递归函数的参数传入的就是根节点和要搜索的数值,返回的就是以这个搜索数值所在的节点。 代码如下: public TreeNode searchBST(TreeNode root, int val) 确定终止条件 如果root为空,返回null&#xff0c…

【前端】HTML常用标签

因为想当个全栈,所以巩固了一下HTML与CSS和JS基础,这一篇博客是HTML部分 文章目录 HTML 基础标签 1HTML 基础框架HTML 基础标签语义标签文本格式化标签div 与 span 标签图像标签超链接特殊字符 基础标签 2 | 表格表格的使用表格标签表格属性表格的头部与…

JavaEE:网络编程

网络编程:通过代码完成基于网络的跨主机通信 跨主机通信方式: 1.TCP/IP网络 2.蓝牙通信 3.近场通信NFC 4.毫米波通信:功率高,带宽高,抗干扰能力差 其中TCP/IP网络是日常编程中最常涉及到的,最通用的跨主机通…

蓝桥杯 2022 dp 背包

蓝桥杯 2022 dp 背包 题目链接&#xff1a; https://www.lanqiao.cn/problems/2186/learning/?subject_code1&group_code4&match_num13&match_flow2&origincup 题目&#xff1a; 代码&#xff1a; #include<bits/stdc.h> using namespace std;#defi…

代码随想录算法训练营第七天| 454.四数相加II、383.赎金信、15.三数之和、18.四数之和

系列文章目录 目录 系列文章目录454.四数相加II使用HashMap法 383.赎金信哈希解法&#xff08;数组&#xff09; 15.三数之和双指针法 18.四数之和双指针法 454.四数相加II 题解&#xff1a;该题和1.两数之和的方法是一样的&#xff0c;这个题的难点在于key和value分别是什么。…