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

【数据结构与算法】时间复杂度和空间复杂度例题

文章目录

  • 时间复杂度
    • 常数阶时间O(1)
    • 对数阶时间O(logN)
    • 线性阶时间O(n)
    • 线性对数阶时间O(nlogN)
    • 平方阶时间O(n*n)
  • 空间复杂度
    • 常量空间O(1)
    • 线性空间O(n)
    • 二维空间O(n*n)
    • 递归空间

时间复杂度

常数阶时间O(1)

  • 代码在执行的时候,它消耗的时间并不随着某个变量的增长而增长,那么无论这类代码有多长,都可以用O(1)来表示它的时间复杂度
  • 我们知道常数项对函数的增长速度影响不大,所以当T(n)=C,C为一个常数的时候,我们说这个算法的时间复杂度为O(1);如果T(n)不等于一个常数项时,直接将常数项省略。
int i=1;
int j=2;
++i;
j++;
int m=i+j;

对数阶时间O(logN)

  • 在while循环里面,每次都将i乘以2,乘完之后,i距离n就越来越近了。我们试着求解一下,假设循环x次之后,i就大于n了,此时这个循环就退出了,也就是说2的x次方等于n,那么x=n
int i=1;
while(i<n)
{
i=i*2;
}

线性阶时间O(n)

  • for循环里面的代码会执行n遍,因此它消耗的时间是随着n的变化而变化的
  • 如果T(n)不等于一个常数项时,直接将常数项省略。因为函数的阶数对函数的增长速度的影响是最显著的,所以我们忽略与最高阶相乘的常数.
  • 我们知道高次项对于函数的增长速度的影响是最大的,同时因为要求的精度不高,所以我们直接忽略低次项。或者说:如果复杂度是多个n的函数之和,则只关心随n的增长而增长得最快的那个函数。
int aFunc(int n){for(int i=0;i<n;i++){             //n+1次printf("Hello,World!\n");     //n次}return 0;                         //1次
}

这个代码需要(n+1+n+1)=2n+2次运算,时间复杂度为O(n)

线性对数阶时间O(nlogN)

  • 将时间复杂度为O(logN)的代码循环n遍的话,那么它的时间复杂度就是n*O(logN),也就是O(nlogN)
for(m=1;m<n;m++){int i=1;while(i<n){i=i*2;}
}

平方阶时间O(n*n)

  • 如果把O(n)的代码再嵌套循环一遍,它的时间复杂度就是O()
  • 如果将其中一层循环的n改成m那它的时间复杂度就变成O(m*n)
for(x=1;i<=n;x++){for(i=1;i<=n;i++){j=i;j++;}
}

【例1】N×N矩阵相乘

for(i=1;i<=n;i++)                          //n+1for(j=1;j<=n;j++){                     //n*(n+1)c[i][j]=0;                         //n*nfor(k=1;k<=n;k++)                  //n*n*(n+1)c[i][j]=c[i][j]+a[i][k]*b[k][j];//T(n)=O(n*n*n)}
  • 级数求和的方式去算

【例2】

for(i=1;i<=n;i++)for(j=1;j<=1;j++)for(k=1;k<=j;k++)x=x+1;

【例3】分析以下程序的时间复杂度

i=1;
while(i<=n)i=i*2;

关键是要找出来执行次数x与n的关系,并完成n的函数。

  • 若循环执行1次:i=1*2=2
  • 若循环执行2次:i=2*2=2^2
  • 若循环执行3次:i=22*2=23,……
  • 若循环执行x次:i=2^x

设语句i=i*2执行次数为x次,由循环条件i<=n,所以2^x<=n,所以x<=log以2为底n

即f(n)<=log以2为底n,取最大值f(n)=log以2为底n

空间复杂度

常量空间O(1)

  • 如果算法执行所需要的临时空间不随着某个变量n的大小而变化,即此算法空间复杂度为一个常量,可表示为O(1)
int i=1;
int j=2;
++i;
j++;
int m=i+j;

线性空间O(n)

  • 这段代码中,第一行new了一个数组出来,这个数据占用的大小为n,这段代码的2-6行,虽然有循环,但没有再分配新的空间。因此,这段代码的空间复杂度主要看第一行即可,即S(n)=O(n)
int[] m=new int[n];
for(i=1;i<=n;++i)
{j=i;j++;
}

【例】将一维数组a中的n个数逆序存放到原数组中。

【算法1】交换数组a中每一个位置的值
for(i=0;i<n/2;i++){t=a[i];         //创建辅助空间t,变量t与n是多少没有关系.S(n)=O(1)a[i]=a[n-i-1];a[n-i-1]=t;
}
【算法2】将a中所有元素依次倒着放入b数组
for(i=0;i<n;i++)b[i]=a[n-i-1]; //创建辅助数组b,b的大小和数组a的大小一样,S(n)=O(n)
for(i=0;i<n;i++)a[i]=b[i];

二维空间O(n*n)

当算法分配的空间是一个二维数组集合,并且集合的长度和宽度都与输入规模n成正比时,空间复杂度记作O()

int[][] matrix=new int[n][n];//O(n^2)
int[][] matrix=new int[m][n];//O(mn)

递归空间

正如下面代码一样,递归代码中没有显示声明变量或者集合,但是计算机在执行程序时,会专门分配一块内存,用来存储“方法调用栈”。

void fun4(int n){if(n<=1){return;}fun4(n-1);...
}

方法调用栈包括入栈和出栈两个操作:

当进入一个新方法时,执行入栈操作,把调用的方法和参数信息压入栈中

当方法返回时,执行出栈操作,把调用的方法和参数信息从栈中弹出

还是上述代码,假设现在传入参数5,那么方法fun4(5)的调用信息先入栈:

method fun4

n 5

接下来递归调用相同的方法,方法fun4(4)的调用信息入栈:

method fun4

n 4

method fun4

n 5

以此类推,递归越来越深,栈内的元素也越来越多,最终:

method fun4

n 1

method fun4

n 2

method fun4

n 3

method fun4

n 4

method fun4

n 5

当n=1的时候,触发递归的结束条件,执行return,方法出栈。最终所有入栈的元素都会出栈。

由上面“方法调用栈”的出入栈过程可以看出,执行递归操作所需要的内存空间和递归的深度成正比。纯粹的递归操作的空间复杂度也是线性的,如果递归的深度是n,那么空间复杂度就是O(n).

相关文章:

【数据结构与算法】时间复杂度和空间复杂度例题

文章目录 时间复杂度常数阶时间O(1)对数阶时间O(logN)线性阶时间O(n)线性对数阶时间O(nlogN)平方阶时间O(n*n) 空间复杂度常量空间O(1)线性空间O(n)二维空间O(n*n)递归空间 时间复杂度 常数阶时间O(1) 代码在执行的时候&#xff0c;它消耗的时间并不随着某个变量的增长而增长…...

停止模式下USART为什么可以唤醒MCU?

在MCU的停止模式下&#xff0c;USART之类的外设时钟是关闭的&#xff0c;但是USART章节有描述到在停止模式下可以用USART来对MCU进行唤醒&#xff1a; 大家是否会好奇在外设的时钟被关闭的情况下&#xff0c;USART怎么能通过接收中断或者唤醒事件对MCU进行唤醒的呢&#xff1…...

Web安全 - 路径穿越(Path Traversal)

文章目录 OWASP 2023 TOP 10导图定义路径穿越的原理常见攻击目标防御措施输入验证和清理避免直接拼接用户输入最小化权限日志监控 ExampleCode漏洞代码&#xff1a;路径穿越攻击案例漏洞说明修复后的安全代码代码分析 其他不同文件系统下的路径穿越特性Windows系统类Unix系统&a…...

JSR303微服务校验

一.创建idea 二.向pom.xml添加依赖 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.7.RELEASE</version></parent><properties><java.vers…...

56. QTreeWidget的基本使用

1. 说明 在软件开发中会遇到将数据信息制作成一种树目录的形式进行展示,那么此时就可以借助QT提供的QTreeWidget控件来实现这种需求,本篇博客会做一个案例简要说明这个控件的基本使用方法,博客中代码能够实现的功能是将此项目代码所在文件夹中的内容展示出来,如下图所示:…...

领域偏移:协变量移位下的域自适应

现在我们将焦点转移到一种叫做协变量转移的扰动上。我们在一个分类或回归设置中工作&#xff0c;我们希望从x预测y&#xff0c;并假设p≈(y | x)和p∗(y | x)是相同的(标记函数在训练和测试之间不会改变) 假设 (Covariate Shift)。对于列车分布p~和检验分布p∗&#xff0c;我们…...

前端开发技术框架选型

一、引言 在前端开发领域&#xff0c;技术框架的选择对于项目的成功至关重要。一个优秀的前端框架不仅可以提高开发效率&#xff0c;还能确保项目的稳定性和可扩展性。而不同的框架具有不同的特点和优势&#xff0c;能够满足不同项目的需求。下面将对目前主流的前端开发技术框…...

/etc/init.d/mysql

Since you’ve installed MySQL from source, you’ll need to create a custom init script to manage the MySQL server (start, stop, status) similarly to a service. Here’s a simple init.d script template for MySQL that you can use. This script assumes MySQL is…...

Qt_线程介绍与使用

目录 1、QThread常用API 2、Qt线程安全 3、使用线程QThread 4、connect函数的第五个参数 5、Qt互斥锁 5.1 QMutexLocker 6、条件变量 7、信号量 结语 前言&#xff1a; 线程是应用程序开发非常重要的概念&#xff0c;在Qt中&#xff0c;用QThread类来实现多线程&a…...

通讯方面的数据,人工智能 机器学习的时候,因为数字都接近于一,数据归一化的一种方法,做了一个简化版本的Z-score标准化

这个表达式实现了一种形式的数据归一化&#xff0c;它将张量x中的每个元素除以x的标准差的估计值。这种处理方式可以使得变换后的数据具有单位标准差&#xff08;假设数据已经是零均值或者在计算过程中考虑了均值&#xff09;。具体来说&#xff0c;它是基于以下步骤进行的&…...

python itertools模块介绍

itertools 是 Python 内建的一个高效处理迭代器的模块&#xff0c;提供了创建复杂迭代器的函数工具。它包含一系列用于迭代、组合、排列、过滤等功能的迭代器构建工具&#xff0c;常用于数据处理和算法设计。下面是 itertools 模块中一些常见的函数介绍&#xff1a; 1. 无限迭…...

【分布式微服务云原生】5分钟深入剖析Kafka:Leader与Follower分区的秘密及负载均衡的艺术

深入剖析Kafka&#xff1a;Leader与Follower分区的秘密及负载均衡的艺术 摘要&#xff1a; Apache Kafka作为当前最流行的分布式流处理平台之一&#xff0c;其内部的分区机制和消费者组的负载均衡策略是实现高吞吐量和高可靠性的关键。本文将深入探讨Kafka中Leader分区与Follo…...

在线代码编辑器

在线代码编辑器 文章说明前台核心代码后台核心代码效果展示源码下载 文章说明 采用Java结合vue3设计实现的在线代码编辑功能&#xff0c;支持在线编辑代码、运行代码&#xff0c;同时支持导入文件&#xff0c;支持图片识别&#xff0c;支持复制代码&#xff0c;可将代码导出为图…...

深入了解 MPlayer:Linux 系统中的多功能多媒体播放器

文章目录 深入了解 MPlayer&#xff1a;Linux 系统中的多功能多媒体播放器一、MPlayer 的安装二、MPlayer 的基本使用三、MPlayer 音频功能详解1. 支持的音频格式2. 调整音频输出设备3. 使用音频滤镜和效果4. 音频输出格式转换5. 多声道与环绕声支持6. 音频控制&#xff1a;播放…...

Netty系列-7 Netty编解码器

背景 netty框架中&#xff0c;自定义解码器的起点是ByteBuf类型的消息, 自定义编码器的终点是ByteBuf类型。 1.解码器 业务解码器的起点是ByteBuf类型 netty中可以通过继承MessageToMessageEncoder类自定义解码器类。MessageToMessageEncoder继承自ChannelInboundHandlerAdap…...

OpenHarmony标准系统上实现对rk系列芯片NPU的支持(npu使用)

在上篇文章中&#xff0c;我们学习了移植rk的npu驱动到OpenHarmony提供的内核。本文我们来学习如何在OpenHarmony标准系统rk系列芯片如何使用npu OpenHarmony RK系列芯片运行npu测试用例 在移植npu驱动到OpenHarmony之后&#xff0c;来运行npu样例进行简单测试 1.O 测试准备…...

大表性能优化的关键技术

1 引言 在现代企业应用中,随着数据量的不断增长,大表的性能优化成为数据库管理的重要环节。本文将探讨大表性能优化的关键技术,包括索引优化、查询优化、分区分表、读写分离以及缓存策略等方面。通过综合运用这些技术,可以显著提升大表的处理效率和响应速度,确保系统的稳…...

广联达 Linkworks办公OA Service.asmx接口存在信息泄露漏洞

漏洞描述 广联达科技股份有限公司以建设工程领域专业应用为核心基础支撑&#xff0c;提供一百余款基于“端云大数据”产品/服务&#xff0c;提供产业大数据、产业新金融等增值服务的数字建筑平台服务商。广联达OA存在信息泄露漏洞&#xff0c;由于某些接口没有鉴权&#xff0c…...

如何成为成功的AI产品经理:经验与策略分享

引言 随着人工智能(AI)技术的迅猛发展,AI产品经理(AI PM)的角色变得越来越重要。Google AI产品负责人Marily Nika在最近的一次播客中分享了她在AI产品管理领域的宝贵经验和见解。本文将整理并总结她的核心内容,帮助有志于进入AI PM领域的人士了解如何准备、所需的核心技…...

spring loCDI 详解

文章目录 一、IoC & DI 基本知识1.1 IoC 的基本概念&#xff1a;1.2 IoC 的优势&#xff1a;1.3 DI 介绍&#xff1a; 二、IoC 详解2.1 Spring 容器&#xff1a;2.2 被存储 Bean 的命名约定&#xff1a;2.3 Bean 的存储方式&#xff1a;2.3.1 五大类注解&#xff1a;2.3.1.…...

基于大模型的 UI 自动化系统

基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

今日科技热点速览

&#x1f525; 今日科技热点速览 &#x1f3ae; 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售&#xff0c;主打更强图形性能与沉浸式体验&#xff0c;支持多模态交互&#xff0c;受到全球玩家热捧 。 &#x1f916; 人工智能持续突破 DeepSeek-R1&…...

【JVM面试篇】高频八股汇总——类加载和类加载器

目录 1. 讲一下类加载过程&#xff1f; 2. Java创建对象的过程&#xff1f; 3. 对象的生命周期&#xff1f; 4. 类加载器有哪些&#xff1f; 5. 双亲委派模型的作用&#xff08;好处&#xff09;&#xff1f; 6. 讲一下类的加载和双亲委派原则&#xff1f; 7. 双亲委派模…...

uniapp 字符包含的相关方法

在uniapp中&#xff0c;如果你想检查一个字符串是否包含另一个子字符串&#xff0c;你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的&#xff0c;但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...

为什么要创建 Vue 实例

核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...

解析奥地利 XARION激光超声检测系统:无膜光学麦克风 + 无耦合剂的技术协同优势及多元应用

在工业制造领域&#xff0c;无损检测&#xff08;NDT)的精度与效率直接影响产品质量与生产安全。奥地利 XARION开发的激光超声精密检测系统&#xff0c;以非接触式光学麦克风技术为核心&#xff0c;打破传统检测瓶颈&#xff0c;为半导体、航空航天、汽车制造等行业提供了高灵敏…...

GraphQL 实战篇:Apollo Client 配置与缓存

GraphQL 实战篇&#xff1a;Apollo Client 配置与缓存 上一篇&#xff1a;GraphQL 入门篇&#xff1a;基础查询语法 依旧和上一篇的笔记一样&#xff0c;主实操&#xff0c;没啥过多的细节讲解&#xff0c;代码具体在&#xff1a; https://github.com/GoldenaArcher/graphql…...

JDK 17 序列化是怎么回事

如何序列化&#xff1f;其实很简单&#xff0c;就是根据每个类型&#xff0c;用工厂类调用。逐个完成。 没什么漂亮的代码&#xff0c;只有有效、稳定的代码。 代码中调用toJson toJson 代码 mapper.writeValueAsString ObjectMapper DefaultSerializerProvider 一堆实…...