数据结构:时间复杂度/空间复杂度

     

目录

一、时间复杂度

定义

常见的时间复杂度

如何计算时间复杂度

计算方法

三、实例分析

二、空间复杂度

定义

重要性

常见的空间复杂度

二、空间复杂度

定义

重要性

常见的空间复杂度

计算方法

三、实例分析

大O的渐进表示法

最好情况(Best Case)6:00

平均情况(Average Case)6:10

最坏情况(Worst Case)6:20

例1:

例2:

例3:

例4

例5


   在计算机科学和算法分析中,时间复杂度和空间复杂度是评估算法效率的两个关键指标。它们帮助我们理解算法在处理数据时所需资源的多少,从而指导我们做出更优的选择。本文将深入浅出地介绍这两个概念,并通过实例加以说明。说白了你在工作当中要让代码的效率变得更好,就需要注意

一、时间复杂度

定义

时间复杂度,简而言之,是指执行算法所需要的计算工作量随着问题规模(通常是输入数据的大小)增长的变化趋势。它关注的是算法运行时间与输入数据规模之间的关系,通常用大O符号表示(O(n)),忽略掉常数项、低阶项以及最高阶的系数。

常见的时间复杂度

  1. O(1) - 常数时间复杂度:算法的执行时间不随输入数据规模变化,如数组访问某个元素。
  2. O(log n) - 对数时间复杂度:二分查找就是一个典型的例子,每一步都将问题规模减半。
  3. O(n) - 线性时间复杂度:遍历数组或列表中的每个元素。
  4. O(n log n) - 线性对数时间复杂度:快速排序、归并排序等高效排序算法。
  5. O(n^2) - 平方时间复杂度:冒泡排序、选择排序等简单排序算法。
  6. O(n^3)O(2^n)O(n!) - 随着问题规模的增长,所需时间急剧增加,分别对应立方、指数、阶乘复杂度。

如何计算时间复杂度

计算方法

空间复杂度的计算方法与时间复杂度相似,也是关注随着问题规模增长,算法所需最大额外空间的变化趋势。

三、实例分析

上面的这些都不能让大家看出复杂度

这里主要举时间复杂度例子

实例1

实例2

实例3

实例4

实例5

  • 找出基本操作:首先确定算法中的基本操作,即执行次数最多的操作。
  • 确定问题规模:用n表示输入数据的大小。
  • 计算增长数量级:分析基本操作的执行次数与n的关系,忽略低阶项和系数,只保留最高阶项。
  • 二、空间复杂度

    定义

    空间复杂度衡量的是算法在运行过程中临时占用存储空间大小的变化情况,同样与问题规模有关。这包括了算法本身占用的空间以及算法运行过程中需要的额外空间。

    重要性

    在内存资源有限的环境下,特别是嵌入式系统或大规模数据处理中,空间复杂度是一个不可忽视的因素。高效利用内存可以提升系统性能,减少资源消耗。

    常见的空间复杂度

  • O(1):算法使用的额外空间不随输入数据规模改变,如原地排序算法。
  • O(n):额外空间正比于输入数据规模,如某些动态规划问题中需要的数组。
  • O(n^2):随着输入规模增大,所需空间平方增长,例如某些矩阵运算。

二、空间复杂度

定义

空间复杂度衡量的是算法在运行过程中临时占用存储空间大小的变化情况,同样与问题规模有关。这包括了算法本身占用的空间以及算法运行过程中需要的额外空间。

重要性

在内存资源有限的环境下,特别是嵌入式系统或大规模数据处理中,空间复杂度是一个不可忽视的因素。高效利用内存可以提升系统性能,减少资源消耗。

常见的空间复杂度

  • O(1):算法使用的额外空间不随输入数据规模改变,如原地排序算法。
  • O(n):额外空间正比于输入数据规模,如某些动态规划问题中需要的数组。
  • O(n^2):随着输入规模增大,所需空间平方增长,例如某些矩阵运算。

计算方法

空间复杂度的计算方法与时间复杂度相似,也是关注随着问题规模增长,算法所需最大额外空间的变化趋势。

三、实例分析

//请计算一下Func1中++count语句总共执行了多少次?
void Funcl(int N)
{
int count =0;
for(int i=0;i<N;++i)
{for(int j=0;j<N;++j){++count;}
}for (int k=0;k<2*N;++k){++count;}int M=10;
while(M--)
{++count;
}printf("%d\n",count);
}

这个代码的时间复杂度是多少嘞?

这边我们看一下我们有一个嵌套循环,外循环执行一次,内循环就要执行N次,所以我们得出了N的平方,再看我们的第二个循环循环的是2*N,下面的while循环10次,由这些依据我们得到一个公式

F(N) = N^2+2*N+10

我们计算时间复杂度有一个大O的渐进表示法来表示,来看个例子:

               精确值                      估算值

N=10      F(N)=130                   100

N=100    F(N)=10210               10000

N=1000  F(N)=1002010           1000000

 实际中我们计算时间复杂度时,我们其实并不一定要计算精确的执行次数,而只需要大概执行次数,那么这 里我们使用大O的渐进表示法。

大O的渐进表示法

由于我们得计算机,运算很快

这个也要看我们的电脑配置

大O渐进表示法,简单来说,是一种衡量算法随着输入数据量增加时,其执行时间或所需资源如何增长的方法。它不关注具体的计算时间,而是关心增长的趋势和速度。

想象一下,你正在研究两个不同的背包打包算法。一个算法检查每件物品与背包内所有可能位置的组合(这可能会导致检查的数量呈指数级增长),而另一个算法则采用更聪明的方法,比如按物品价值和重量预先排序(这样可能最多只需检查每个物品一次)。为了比较这两个算法哪个在面对大量物品时表现更好,我们就需要用到大O表示法。

通过上面我们会发现大O的渐进表示法去掉了那些对结果影响不大的项,简洁明了的表示出了执行次数。

举个例子吧,假如你今天在看我的博客,但是你女朋友给你发消息说晚上出来玩,然后叫你定个时间,于是就出来三种情况

最好情况(Best Case)6:00
  • 描述:博客非常短,你几乎立刻就读完了。
  • 算法复杂度:在这种情况下,无论博客多长,你都能瞬间完成阅读并回复消息。这类似于一个常数时间操作,可以用O(1)表示,意味着操作时间不随输入大小变化。
平均情况(Average Case)6:10
  • 描述:博客的长度中等,既不太长也不太短,你需要花一些合理的时间阅读。
  • 算法复杂度:如果大多数时候博客的长度在一个可预期的范围内,且阅读时间与博客长度成正比,那么这可以视为线性时间复杂度,即O(n),其中n代表博客的字数。这意味着阅读时间随博客长度线性增长。
最坏情况(Worst Case)6:20
  • 描述:博客异常长,需要很长时间才能读完。
  • 算法复杂度:在这种情况下,如果阅读时间直接与博客的长度成正比(忽略可能的加载时间等其他因素),复杂度仍然是O(n)。但如果考虑到随着博客越来越长,你的注意力可能会分散,导致阅读每个额外字词所需时间轻微增加,这种情况下虽然仍是线性关系,但强调了在极端条件下的体验。

这三种情况,你选哪一个最保险?才能不让你的女朋友等你嘞?所以我们有时候不要把预期拉的太高,做事要想好最坏的打算

通过这些我们回到上面的代码我们就可以得出他的时间复杂度是O(n^2),因为他影响最大,也是最坏的那个

接下来我们看几个例子来练习一下

例1:
//计算Func3的时间复杂度?
void Func3(int N,int M)
{
int count =0;
for (int k=0;k<M;++k)
{
++count;
}
}
for (int k=0;k<N;++k)
{
++count;
}
printf("%d\n",count);

F(M+N)

这里没有明确说明N远大于M还是M远大于N,都没有明确说明,那就是对执行次数影响是同等的,谁都不能舍去,所以结果为O(N)=N+M。

例2:
//计算Func4的时间复杂度?
void Func4(int N)
{
int count =0;
for (int k =0;k<100;++k)
{
++count;
}
printf("%d\n",count);
}

大家看一下这个时间复杂度是多少?

这个循环一共执行了100次,这个100是一个常数,所以我们这里的空间复杂度是O(1)(就是我们可以看出来的次数,执行次数不是未知数

例3:

例4

这个就要根据逻辑理解这个O(2^N)

例5

空间复杂度不是程序占用了多少bytes的空间,因为这个也没太大意义,所以空间复杂度算的是变量的个数。 空间复杂度计算规则基本跟实践复杂度类似,也使用大O渐进表示法。

注意:函数运行时所需要的栈空间(存储参数、局部变量、一些寄存器信息等)在编译期间已经确定好了,因 此空间复杂度主要通过函数在运行时候显式申请的额外空间来确定。

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

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

相关文章

spring框架学习记录(1)

前半个月一直在应付期中考试&#xff0c;快被折磨似了orz 文章目录 SpringIoC(Inversion of Control) 控制反转与DI(Dependency Injection)依赖注入bean相关bean配置bean实例化bean的生命周期 依赖注入相关依赖注入方式依赖自动装配 容器创建容器获取bean Spring IoC(Inversi…

leetcode295. 数据流的中位数

class MedianFinder {//A为小根堆&#xff0c;B为大根堆List<Integer> A,B;public MedianFinder() {A new ArrayList<Integer>();B new ArrayList<Integer>();}public void addNum(int num) {int m A.size(),n B.size();if(m n){insert(B,num);int top …

BeanFactory 源码浅析

BeanFactory 功能介绍 BeanFactory 是核心容器&#xff0c;负责管理 Bean 对象 BeanFactory 接口的功能只有一个 getBean() 方法BeanFactory 的实现类&#xff08;DefaultListableBeanFactory&#xff09;包含&#xff1a;控制反转、基本的依赖注入、Bean 生命周期的各种功能…

从浏览器输入url到页面加载(八)你的web网站有几台服务器?

你有没有想过一个问题&#xff0c;做为一名前端开发&#xff0c;你的网站上线后&#xff0c;准备了几台服务器&#xff1f;前端静态资源用了几台&#xff0c;你调接口的那个后端部署了几台&#xff1f; 目录 1 没接触过这个问题很正常 2 当访问量上升的时候 2.1 提升带宽 …

绝了!这是我见过最详细的HashMap源码解析

1 概述 HashMap是基于哈希表实现的,每一个元素是一个key-value对,其内部通过单链表解决冲突问题,容量不足(超过了阀值)时,同样会自动增长. HashMap是非线程安全的,只适用于单线程环境,多线程环境可以采用并发包下的concurrentHashMap HashMap 实现了Serializable接口&#x…

ArmSoM-Sige5 RK3576开发板 正式发布!

简介​ ArmSoM-Sige5 采用Rockchip RK3576第二代8nm高性能AIOT平台&#xff0c;6 TOPS算力NPU&#xff0c;最大可配16GB大内存。支持8K视频编解码&#xff0c;拥有丰富的接口&#xff0c;支持双千兆网口&#xff0c;WiFi6 & BT5和多种视频输出。支持多种操作系统&#xff…

HTML5实用大全(Part.2)

引言&#xff1a; 哈喽&#xff0c;各位小伙伴们大家好呀&#xff0c;学习了上一篇关于HTML5的文章后&#xff0c;你是否对于入门HTML5有了一定的基础了呢&#xff0c;本篇博客我们将继续学习HTML5的不同标签&#xff0c;跟上队伍&#xff0c;准备出发咯&#xff01; 1.标签之…

2024五一杯数学建模竞赛A题完整成品论文和代码分析:建立钢板切割的工艺路径动态规划、贪心与分层优化模型

2024五一杯数学建模竞赛A题&#xff1a;建立钢板切割的工艺路径动态规划、贪心与分层优化模型 2024五一数学建模A题完整代码和成品论文获取↓↓↓↓↓ https://www.yuque.com/u42168770/qv6z0d/gyoz9ou5upvkv6nx?singleDoc# 本文文章较长&#xff0c;建议先目录。经过不懈的…

三星一季度利润飙涨932%!AI引爆存储热,未来研发狠砸AI

⏩三星一季度利润飙涨932%&#xff01;AI引爆存储热&#xff0c;未来研发狠砸AI 三星电子公布了第一季度财报数据&#xff0c;显示其利润飙涨932.8%。得益于AI拉动的广泛支出&#xff0c;三星电子一季度利润激增。三星表示&#xff0c;预计第二季度业务将主要由生成式人工智能…

算法学习系列(五十四):单源最短路的综合应用

目录 引言一、新年好二、通信线路三、道路与航线四、最优贸易 引言 关于这个单源最短路的综合应用&#xff0c;其实最短路问题最简单的就是模板了&#xff0c;这是一个基础&#xff0c;然后会与各种算法结合到一块&#xff0c;就是不再考察单个知识点了&#xff0c;而是各种知…

ASP.NET图书馆管理信息系统

摘  要 本文首先阐述了基于.NET Framework平台的图书馆管理信息系统的开发背景以及其实践意义&#xff0c;其次说明了图书馆管理信息系统的功能以及相比同类软件的创新之处。然后就图书馆管理系统开发中所使用的一些的技术进行研究探讨。主要针对数据库的设计技术、存储过程…

Copilot Venture Studio創始合伙人楊林苑確認出席“邊緣智能2024 - AI開發者峰會”

隨著AI技術的迅猛發展&#xff0c;全球正逐步進入邊緣計算智能化與分布式AI深度融合的新時代&#xff0c;共同書寫著分布式智能創新應用的壯麗篇章。邊緣智能&#xff0c;作為融合邊緣計算和智能技術的新興領域&#xff0c;正逐漸成為推動AI發展的關鍵力量。借助分布式和去中心…

Docker——部署LNMP架构

目录 一、LNMP架构概述 1.项目环境 2.服务器环境 3.需求 二、搭建Linux系统基础镜像 三、部署Nginx 1.建立工作目录 2.编写Dockerfile脚本 3.准备Nginx.conf配置文件 4.生成镜像 5.创建自定义网络 6.启动镜像容器 7.验证Nginx 三、部署Mysql 1.建立工作目录 2.编…

【Docker第一课】docker的基本命令和试启动容器(详细图解)

目录 知识梗概 docker的初步了解 了解docker常用命令 试开启容器&#xff08;这里演示nginx、python3和mysql&#xff09; 1、nginx容器的启动 2、python3容器的启动 docker的作用 虚拟机与容器的区别 写在前面&#xff1a; 本专栏你将了解docker一些入门知识&#xff…

如何使用 ArcGIS Pro 查找小区最近的地铁站

学习 GIS 除了可以用在工作上之外&#xff0c;还可以将其运用到生活之中&#xff0c;比如查找距离小区最近的地铁站&#xff0c;这里为大家介绍一下查找的方法&#xff0c;希望能对你有所帮助。 数据来源 教程所使用的数据是从水经微图中下载的POI数据&#xff0c;除了POI数据…

a-table 控制列的展示和隐藏

一、业务场景&#xff1a; 最近在使用 Antd-vue 组件库的时候&#xff0c;a-table需要根据不同角色的权限显示和隐藏 columns的列 为了避免大家走弯路&#xff0c;为大家整理了一下&#xff0c;粘走可以直接用的那种 二、具体实现步骤&#xff1a; 1.在需要显示与隐藏的列增加一…

Git客户端(TortoiseGit)使用详解

1.概述 使用TortoiseGit比直接使用git 客户端和命令实现代码版本管理更为方便&#xff0c;本文根据实际使用情况作一些记录&#xff0c;特别是对于解决冲突的处理。 2.Git安装与配置 下载 Git - Downloads&#xff0c; 可参考Git安装步骤完成Git的安装与配置。 3.TortoiseG…

python学习笔记B-20:序列实战--处理千年虫

将2位数表达的年份&#xff0c;转换为用4位数表达&#xff1a; print("将列表中的2位数年份转换为4位数年份") lst[88,89,90,00,99] print(lst) for index in range(len(lst)):if len(str(lst[index]))2:lst[index] 1900int(lst[index])elif len(str(lst[index]))1…

收单外包机构备案情况分析,广东备案机构遥遥领先

孟凡富 4月30日&#xff0c;中国支付清算协会公示了最新一批收单外包服务备案机构&#xff0c;较上期增加了689家。其中&#xff0c;新增聚合支付技术服务备案机构达6家。截至4月末&#xff0c;备案的收单外包服务机构总数为27714家&#xff0c;同时取消了330家机构的备案资格&…

spring-security 学习笔记一 --- 基于默认配置

1.前言 本文主要讲解 spring-security 在不做任何配置情况下&#xff0c;它的启动流程和认证过程。 1. 准备工作 这里是基于springboot 2.2.5版本对应 spring-security 5.2.2版本演示的 &#xff08;按我下面导入即可&#xff0c;版本是它自己匹配的&#xff09; 引入依赖 &…