当前位置: 首页 > news >正文

算法时空复杂度分析:大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表示法

文章目录 前言大O表示法3个时间复杂度分析原则常见的时间复杂度量级空间复杂度参考资料 前言 算法题写完以后,面试官经常会追问一下你这个算法的时空复杂度是多少?(好像作为一名算法工程师,我日常码代码的过程中,并没…...

threejs简单创建一个几何体(一)

1.下包引入 //下包 npm install three yarn add three//引入 import * as THREE from three2.创建场景,摄像机 // 1.创建场景const scene new THREE.Scene()// 2.创建摄像机//第一个参数是视角,一般在60-90之间,第二个参数是场景的尺寸,一般取显示器的宽高,第三个参数是开始位…...

msfconsole数据库连接不了的问题【已解决】

msfconsole数据库连接 1.msf数据库端口 msf使用的是postgresql,这个数据库默认端口是5432 单个模块的使用可以不需要数据库,但是模块与模块之间需要沟通的时候就会用到数据库。 2.查看msf数据库连接状态 db_status #msf内部查看systemctl status p…...

7. Linux进程环境

进程是操作系统运行程序的一个实例,也是操作系统分配资源的单位。在Linux环境中,每个进程都有独立的进程空间,以便对不同的进程进行隔离,使之不会互相影响。深入理解Linux下的进程环境, 可以帮助我们写出更健壮的代码。 在 Linux 中,进程是程序的一次执行过程,它包含了程…...

[linux] 静态图和动态图

动态图(Dynamic Graphs)和静态图(Static Graphs)通常用来描述深度学习框架中模型的构建方式。 静态图(Static Graphs) 静态图是指模型的计算图在运行前就被定义好并且编译优化的方式。也就是说&#xff0c…...

1.Spring核心功能梳理

概述 本篇旨在整体的梳理一下Spring的核心功能,让我们对Spring的整体印象更加具体深刻,为接下来的Spring学习打下基础。 本片主体内容如下: Bean的生命周期依赖注入的实现Bean初始化原理推断构造方法原理AOP的实现这里要说明一下,我们这里说到的Spring,一般指的是Spring F…...

活动预告:如何培养高质量应用型医学人才?

在大数据时代与“新医科”建设的背景下,掌握先进的医学数据处理技术成为了医学研究与应用的重要技能。 为了更好地培养社会所需要的高质量应用型医学人才,许多高校已经在广泛地开展面向医学生的医学数据分析教学工作。 在“课-训-赛”育人才系列活动的…...

蓝桥杯算法错题记录-基础篇

文章目录 本文还在跟新,最新跟新时间3/11!!! 格式一定要符合要求,(输入,输出格式)1. nextInt () next() nextLine() 的注意事项2 .数的幂 a^2等3.得到最大长度(最大...&a…...

Java知识点之单例模式

1、单例模式(Binary Search) 单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。这些应用都或多或少具有资…...

Flutter第三弹:常用的Widget

目标: 1)常用的Widget有哪些?有什么特征? 2)开发一个简单的登录页面。 一、Flutter常用Widget 对于Flutter来说,一切皆Widget. 常用的Widget,包括一些基础功能的Widget. 控件名称功能备注…...

Dynamic Wallpaper v17.4 mac版 动态视频壁纸 兼容 M1/M2

Dynamic Wallpaper Engine 是一款适用于 Mac 电脑的视频动态壁纸, 告别单调的静态壁纸,拥抱活泼的动态壁纸。内置在线视频素材库,一键下载应用,也可导入本地视频,同时可以将视频设置为您的电脑屏保。 应用介绍 Dynam…...

Windows / Mac应用程序在Linux系统中的兼容性问题 解决方案

Linux系统可以通过多种方式提高与Windows或Mac应用程序的兼容性。这里有一些解决方案 Windows应用程序兼容性解决方案: Wine Wine是一个允许Linux和Unix系统上运行Windows应用程序的兼容层。 它不是模拟器,而是实现了Windows API的开源实现。 许多W…...

Net Core 使用Mongodb操作文件(上传,下载)

Net Core 使用Mongodb操作文件(上传,下载) 1.Mongodb GridFS 文件操作帮助类。 GridFS 介绍 https://baike.baidu.com/item/GridFS/6342715?fraladdin DLL源码:https://gitee.com/chenjianhua1985/mongodb-client-encapsulati…...

适用于系统版本:CentOS 6/7/8的基线安全检测脚本

#!/bin/bash #适用于系统版本:CentOS 6/7/8 echo "----------------检测是否符合密码复杂度要求----------------" #把minlen(密码最小长度)设置为8-32位,把minclass(至少包含小写字母、大写字母、数字、特殊…...

Seata源码流程图

1.第一阶段分支事务的注册 流程图地址:https://www.processon.com/view/link/6108de4be401fd6714ba761d 2.第一阶段开启全局事务 流程图地址:https://www.processon.com/view/link/6108de13e0b34d3e35b8e4ef 3.第二阶段全局事务的提交 流程图地址…...

英飞凌电源管理PMIC的安全应用

摘要 本篇文档主要用来介绍英飞凌电源管理芯片TLF35584的使用,基于电动助力转向应用来介绍。包含一些安全机制的执行。 TLF35584介绍 TLF35584是英飞凌推出的针对车辆安全应用的电源管理芯片,符合ASIL D安全等级要求,具有高效多电源输出通道&…...

快速在Linux系统安装MySQL

虚拟机使用docker安装MySQL 使用docker拉去镜像 查看mysql的镜像 docker search mysql拉去mysql镜像 docker pull mysql查看下载的镜像 docker images启动容器 docker start mysql进入MySQL容器 docker exec -it mysql /bin/bash登录mysql mysql -u root -p检查是否进入…...

数据库相关理论知识(有目录便于直接锁定相关知识点+期末复习)

一,数据模型,关系型数据模型,网状模型,层次模型 1.数据库模型是用来描述和表示现实世界中的事物、概念以及它们之间的关系的工具,但是并不是越专业越好,还要平衡它的模型的复杂性、通用性和成本效益等因素…...

NCC环境配置

一、后端配置 1.安装eclipse汉化插件 2.安装svn插件...

用python实现Dubins曲线生成

Dubins曲线是连接两个具有指定方向和位置的点的最短路径,其中路径受到固定曲率约束(如车辆的转向限制)。Dubins曲线常用于机器人路径规划、车辆轨迹规划等领域。 Dubins曲线可以分为三种类型:CCC (Curve-Curve-Curve), CCL (Curv…...

智能技术上的“是”并不代表具体领域的“应该”

技术上的“是”并不代表具体领域的“应该” 。技术上的“是”仅仅是指某种方法或技术在实践中是否可行或有效,而不涉及是否该采取这种方法或技术。决定是否采取某种方法或技术还需要考虑伦理、法律、可行性等其他方面的因素。技术的发展可能会有各种可能性&#xff…...

永热爱 敢向前 | Paraverse平行云的2023 年终总结

永热爱,敢向前 值此新年,回顾2023,仅以此句,献给所有XR产业信仰者 2023 年,是XR产业技术和场景承上启下的关键之年 在这场波澜壮阔的技术潮中 「Paraverse平行云」踏浪前行 已是第八个年头,让我们一起…...

c/c++的内存分配,详细说一下栈、堆和静态存储区

栈区(Stack):由编译器自动分配和回收,栈中存放函数调用的相关信息,栈帧(记录函数的栈帧开始的位置),参数,局部变量,返回地址。其操作方法类似于数据结构中的栈…...

每日构造题训练——C. Divan and bitwise operations

每日构造题训练 题目链接: 题目传送门 前置知识: 按位或运算 一、题意: 1 1 1、 有一个长度为 n n n的但是元素未知的数组 a a a, 给定 m m m个约束&#xff0c;每个约束都有 l , r , x l, r, x l,r,x, 并且满足 1 ≤ l ≤ r ≤ n , 1 ≤ x < 2 30 , a [ l ] ∣ a [ l 1 …...

【C++练级之路】【Lv.13】多态(你真的了解虚函数和虚函数表吗?)

快乐的流畅&#xff1a;个人主页 个人专栏&#xff1a;《C语言》《数据结构世界》《进击的C》 远方有一堆篝火&#xff0c;在为久候之人燃烧&#xff01; 文章目录 一、虚函数与重写1.1 虚函数1.2 虚函数的重写1.3 重写的特例1.4 final和override&#xff08;C11&#xff09;1.…...

如何在Windows系统安装Node.js环境并制作html页面发布公网远程访问?

文章目录 前言1.安装Node.js环境2.创建node.js服务3. 访问node.js 服务4.内网穿透4.1 安装配置cpolar内网穿透4.2 创建隧道映射本地端口 5.固定公网地址 前言 Node.js 是能够在服务器端运行 JavaScript 的开放源代码、跨平台运行环境。Node.js 由 OpenJS Foundation&#xff0…...

C#,数值计算,希尔伯特矩阵(Hilbert Matrix)的算法与源代码

Hilbert, David (1862-1943) 1 希尔伯特(Hilbert) 德国数学家,在《几何学基础》中提出了第一套严格的几何公理(1899年)。他还证明了自己的系统是自洽的。他发明了一条简单的空间填充曲线,即埃里克魏斯汀的数学世界,即希尔伯特曲线,埃里克魏斯汀的数学世界,并证明了不…...

【C++教程从0到1入门编程】第八篇:STL中string类的模拟实现

一、 string类的模拟实现 下面是一个列子 #include <iostream> namespace y {class string{public: //string() //无参构造函数// :_str(nullptr)//{}//string(char* str) //有参构造函数// :_str(str)//{}string():_str(new char[1]){_str[0] \0;}string(c…...

学生时期学习资源同步-1 第一学期结业考试题6

原创作者&#xff1a;田超凡&#xff08;程序员田宝宝&#xff09; 版权所有&#xff0c;引用请注明原作者&#xff0c;严禁复制转载...

迁移学习怎么用

如果想实现一个计算机视觉应用&#xff0c;而不想从零开始训练权重&#xff0c;比方从随机初始化开始训练&#xff0c;更快的方式是下载已经训练好权重的网络结构&#xff0c;把这个作为预训练&#xff0c;迁移到你感兴趣的新任务上。ImageNet、PASCAL等等数据库已经公开在线。…...