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

时间复杂度与空间复杂度的详解

目录

1.时间复杂度

2.时间复杂度计算例题

3.空间复杂度


1.时间复杂度

算法中的基本操作的执行次数,为算法的时间复杂度。
如何表达 时间复杂度?
大O的渐进表示法
实际中我们计算时间复杂度时,我们其实并不一定要计算精确的执行次数,而只需要 大概执行次数,那么这里我们 使用大 O 的渐进表示法。
1、用常数1取代运行时间中的所有加法常数。
2、在修改后的运行次数函数中,只保留最高阶项。
3、如果最高阶项存在且不是1,则去除与这个项目相乘的常数。得到的结果就是大O

举例:

 

// 请计算一下 func1 基本操作执行了多少次?
void func1 ( 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 -- ) > 0 ) {
count ++ ;
}
System . out . println ( count );
}

 题解:

Func1 执行的基本操作次数 :
F(N)=N^2+2*N+10;
(1) 用常数1取代运行时间中的所有加法常数。
F(N)=N^2+2*N+1;
(2) 在修改后的运行次数函数中,只保留最高阶项。
F(N)=N^2;
=>O(N^2);

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

另外有些算法的时间复杂度存在最好、平均和最坏情况:
最坏情况:任意输入规模的最大运行次数 ( 上界 )
平均情况:任意输入规模的期望运行次数
最好情况:任意输入规模的最小运行次数 ( 下界 )
在实际中一般情况关注的是算法的最坏运行情况,如:数组中搜索数据时间复杂度为 O(N)
O(N)中N表示问题的规模

2.时间复杂度计算例题

例题1:

// 计算 func2 的时间复杂度?
void func2 ( int N , int M ) {
int count = 0 ;
for ( int k = 0 ; k < M ; k ++ ) {
count ++ ;
}
for ( int k = 0 ; k < N ; k ++ ) {
count ++ ;
}
System . out . println ( count );
}

答案及分析:

基本操作执行了M+N次,有两个未知数MN,时间复杂度为 O(N+M) 

例题2:

// 计算 func3 的时间复杂度?
void func3 int N ) {
int count = 0 ;
for ( int k = 0 ; k < 100 ; k ++ ) {
count ++ ;
}
System . out . println ( count );
}

 答案及分析:

基本操作执行了100次,通过推导大O阶方法,时间复杂度为 O(1)

 例题3:

// 计算 bubbleSort 的时间复杂度?
void bubbleSort ( int [] array ) {
for ( int end = array . length ; end > 0 ; end -- ) {
boolean sorted = true ;
for ( int i = 1 ; i < end ; i ++ ) {
if ( array [ i - 1 ] > array [ i ]) {
Swap ( array , i - 1 , i );
sorted = false ;
}
}
if ( sorted == true ) {
break ;
}
}
}

 答案及分析:

O(N)中N表示问题的规模

F(N)=N*(N-1)=N^2-N;

通过推导大 O 阶方法 + 时间复杂度一般看最坏,时间 复杂度为 O(N^2)

 例题4:

// 计算 binarySearch 的时间复杂度?
int binarySearch ( int [] array , int value ) {
int begin = 0 ;
int end = array . length - 1 ;
while ( begin <= end ) {
int mid = begin + (( end - begin ) / 2 );
if ( array [ mid ] < value )
begin = mid + 1 ;
else if ( array [ mid ] > value )
end = mid - 1 ;
else
return mid ;
}
return - 1 ;
}

 答案及分析:

方法1:

对于不能直接看出的并较复杂的问题,可以采用数学归纳法

 答案:

 方法2:

 

N/(2^x) =1(x为循环的执行次数)

x的解:

例题 5

// 计算阶乘递归 factorial 的时间复杂度?
long factorial ( int N ) {
return N < 2 ? N : factorial ( N - 1 ) * N ;
}

对于不能直接看出的并较复杂的问题,可以采用数学归纳法,但对于递归我们有专门总结的方法。

F(N)=递归的次数*每次递归代码的执行次数

 答案及分析:

通过计算分析发现基本操作递归了 N次, 每次递归代码的执行次数为1 时间复杂度为O(N)

例题6:

// 计算斐波那契递归 fifibonacci 的时间复杂度?
int fifibonacci ( int N ) {
return N < 2 ? N : fifibonacci ( N - 1 ) + fifibonacci ( N - 2 );
}

  答案及分析:

对于不能直接看出的并较复杂的问题,可以采用数学归纳法(不展开)

面对这种多递归入口的题,可以使用补全法。

何为补全法?

以F4为例

F(N): 

 

1+2+4+……+2^(N-1)
=2^N-1;
O(2^N)

3.空间复杂度

空间复杂度是对一个算法在运行过程中 临时占用存储空间大小的量度 。空间复杂度不是程序占用了多少 bytes 的空 间,因为这个也没太大意义,所以空间复杂度算的是变量的个数
空间复杂度计算规则基本跟时间复杂度类似 ,也 使用 O 渐进表示法
无论什么类型,只看开了多少的空间

 例题1:

// 计算 bubbleSort 的空间复杂度?
void bubbleSort ( int [] array ) {
for ( int end = array . length ; end > 0 ; end -- ) {
boolean sorted = true ;
for ( int i = 1 ; i < end ; i ++ ) {
if ( array [ i - 1 ] > array [ i ]) {
Swap ( array , i - 1 , i );
sorted = false ;
}
}
if ( sorted == true ) {
break ;
}
}
}

   答案及分析:

 使用了常数个额外空间,所以空间复杂度为 O(1)

例题2:

// 计算 fifibonacci 的空间复杂度?
int [] fifibonacci ( int n ) {
long [] fifibArray = new long [ n + 1 ];
fifibArray [ 0 ] = 0 ;
fifibArray [ 1 ] = 1 ;
for ( int i = 2 ; i <= n ; i ++ ) {
fifibArray [ i ] = fifibArray [ i - 1 ] + fifibArray [ i - 2 ];
}
return fifibArray ;
}

 答案及分析:

动态开辟了N个空间,空间复杂度为 O(N)

例题3:

// 计算阶乘递归 Factorial 的空间复杂度?
long factorial ( int N ) {
return N < 2 ? N : factorial ( N - 1 ) * N ;
}

  答案及分析:

递归调用了 N 次,开辟了 N 个栈帧,每个栈帧使用了常数个空间。空间复杂度为 O(N)

 

以上为我个人的小分享,如有问题,欢迎讨论!!! 

都看到这了,不如关注一下,给个免费的赞 

 

 

相关文章:

时间复杂度与空间复杂度的详解

目录 1.时间复杂度 2.时间复杂度计算例题 3.空间复杂度 1.时间复杂度 算法中的基本操作的执行次数&#xff0c;为算法的时间复杂度。 如何表达 时间复杂度&#xff1f; 大O的渐进表示法 实际中我们计算时间复杂度时&#xff0c;我们其实并不一定要计算精确的执行次数&#xf…...

每日一学:什么是 Harbor ?

目录 什么是 Harbor &#xff1f; 一、Harbor 的优势 二、Harbor 架构构成 三、Core services 这是 Harbor 的核心功能 什么是 Harbor &#xff1f; Harbor 是 VMware 公司开源的企业级 Docker Registry 项目&#xff0c;其目标是帮助用户迅速搭建一个企业级的 Docker Reg…...

灰度均衡变换之c++实现(qt + 不调包)

1.基本原理 灰度均衡是以累计分布函数变换为基础的直方图修正法&#xff0c;它可以产生一副灰度级分布概率均匀的图像。也就是说&#xff0c;经过灰度均衡后的图像在没一级灰度上像素点的数量相差不大。公式见下图&#xff0c;为灰度值为x的像素点的个数&#xff0c;n为总像素点…...

flink1.17 自定义trigger ContinuousEventTimeTrigger

在 ContinuousEventTimeTrigger 的基础上新增了timeout,如果超时后窗口都没关闭,那么就硬输出一波,避免间断数据,留存窗口太久. ContinuousEventTimeTrigger ContinuousEventTimeTrigger连续事件时间触发器与ContinuousProcessingTimeTrigger连续处理时间触发器,指定一个固定…...

AIGC:【LLM(五)】——Faiss:高效的大规模相似度检索库

文章目录 一.简介1.1 什么是Faiss1.2 Faiss的安装 二.Faiss检索流程2.1 构建向量库2.2 构建索引2.3 top-k检索 三.Faiss构建索引的多种方式3.1 Flat &#xff1a;暴力检索3.2 IVFx Flat &#xff1a;倒排暴力检索3.3 IVFxPQy 倒排乘积量化3.4 LSH 局部敏感哈希3.5 HNSWx 一.简介…...

自然语言处理从入门到应用——LangChain:记忆(Memory)-[记忆的类型Ⅱ]

分类目录&#xff1a;《自然语言处理从入门到应用》总目录 对话知识图谱记忆&#xff08;Conversation Knowledge Graph Memory&#xff09; 这种类型的记忆使用知识图谱来重建记忆&#xff1a; from langchain.memory import ConversationKGMemory from langchain.llms impo…...

桥接模式-java实现

桥接模式 桥接模式的本质&#xff0c;是解决一个基类&#xff0c;存在多个扩展维度的的问题。 比如一个图形基类&#xff0c;从颜色方面扩展和从形状上扩展&#xff0c;我们都需要这两个维度进行扩展&#xff0c;这就意味着&#xff0c;我们需要创建一个图形子类的同时&#x…...

Linux systemd管理常用的几个小案例

systemd是目前Linux系统上主要的系统守护进程管理工具&#xff0c;配置文件要以.service结尾且放到 /usr/lib/systemd/system/目录下面 1、systemd管理ElasticSearch [Unit] DescriptionElasticsearch Service[Service] Typeforking Userelastic Groupelastic ExecStart/home…...

38、IPv6过渡技术

本节内容作为IPv6相关知识的最后一节内容&#xff0c;同时也作为我们本专栏网络层知识的最后一节内容&#xff0c;主要介绍从IPv4地址到IPv6地址过渡的相关技术。在这里我们只学习各类考试中常考的三种技术。 IPv4向IPv6的过渡 在前面的知识中&#xff0c;我们学习到了两种IP地…...

HMMER-序列分析软件介绍

HMMER是一个软件包&#xff0c;它提供了制作蛋白质和DNA序列域家族概率模型的工具&#xff0c;称为轮廓隐马尔可夫模型、轮廓HMM或仅轮廓&#xff0c;并使用这些轮廓来注释新序列、搜索序列数据库以寻找其他同源物&#xff0c;以及进行深度多重序列比对。HMMER是已知蛋白质和DN…...

【项目学习1】如何将java对象转化为XML字符串

如何将java对象转化为XML字符串 将java对象转化为XML字符串&#xff0c;可以使用Java的XML操作库JAXB&#xff0c;具体操作步骤如下&#xff1a; 主要分为以下几步&#xff1a; 1、创建JAXBContext对象&#xff0c;用于映射Java类和XML。 JAXBContext jaxbContext JAXBConte…...

nginx负载均衡

负载均衡&#xff1a;反向代理来实现 正向代理的配置方法。 1、NGINX的七层代理和四层代理&#xff1a; 七层是最常用的反向代理方式&#xff0c;只能配置在nginx配置文件的http模块。而且配置方法名称&#xff1a;upstream 模块&#xff0c;不能写在server中&#xff0c;也…...

【毕业项目】自主设计HTTP

博客介绍&#xff1a;运用之前学过的各种知识 自己独立做出一个HTTP服务器 自主设计WEB服务器 背景目标描述技术特点项目定位开发环境WWW介绍 网络协议栈介绍网络协议栈整体网络协议栈细节与http相关的重要协议 HTTP背景知识补充特点uri & url & urn网址url HTTP请求和…...

关于安卓jar包修改并且重新发布

背景&#xff1a; 对于某些jar包&#xff0c;其内部是存在bug的&#xff0c;解决的方法无外乎就有以下几种方法&#xff1a; &#xff08;1&#xff09;通过反射&#xff0c;修改其赋值逻辑 &#xff08;2&#xff09;通过继承&#xff0c;重写其方法 &#xff08;3&#xff0…...

Java课题笔记~ AspectJ 对 AOP 的实现(掌握)

AspectJ 对 AOP 的实现(掌握) 对于 AOP 这种编程思想&#xff0c;很多框架都进行了实现。Spring 就是其中之一&#xff0c;可以完成面向切面编程。然而&#xff0c;AspectJ 也实现了 AOP 的功能&#xff0c;且其实现方式更为简捷&#xff0c;使用更为方便&#xff0c;而且还支…...

npm 报错 cb() never called!

不知道有没有跟我一样的情况&#xff0c;在使用npm i的时候一直报错&#xff1a;cb() never called! 换了很多个node版本&#xff0c;还是不行&#xff0c;无法解决这个问题 百度也只是让降低node版本请缓存&#xff0c;gpt给出的解决方案也是同样的 但是缓存清过很多次了&a…...

finally有什么作用以及常用场景

在Java中&#xff0c;finally是一个关键字&#xff0c;用于定义一个代码块&#xff0c;该代码块中的代码无论是否发生异常都会被执行。finally块通常用于确保在程序执行过程中资源的释放和清理。 使用场景&#xff1a; 1. 资源释放&#xff1a;finally块经常用于释放打开的资…...

Python web实战之Django URL路由详解

概要 技术栈&#xff1a;Python、Django、Web开发、URL路由 Django是一种流行的Web应用程序框架&#xff0c;它采用了与其他主流框架类似的URL路由机制。URL路由是指将传入的URL请求映射到相应的视图函数或处理程序的过程。 什么是URL路由&#xff1f; URL路由是Web开发中非常…...

10-数据结构-队列(C语言)

队列 目录 目录 队列 一、队列基础知识 二、队列的基本操作 1.顺序存储 ​编辑 &#xff08;1&#xff09;顺序存储 &#xff08;2&#xff09;初始化及队空队满 &#xff08;3&#xff09;入队 &#xff08;4&#xff09;出队 &#xff08;5&#xff09;打印队列 &…...

面试之快速学习C++11 - 右值 移动构造 std::move

C11右值引用 字面意思&#xff0c;以引用传递的方式使用c右值左值和右值&#xff0c;左值是lvalue loactor value 存储在内存中&#xff0c;有明确存储地址的数据&#xff0c; 右值rvalue read value , 指的是那些可以提供数据值的数据&#xff08;不一定可以寻址&#xff0c;…...

idea大量爆红问题解决

问题描述 在学习和工作中&#xff0c;idea是程序员不可缺少的一个工具&#xff0c;但是突然在有些时候就会出现大量爆红的问题&#xff0c;发现无法跳转&#xff0c;无论是关机重启或者是替换root都无法解决 就是如上所展示的问题&#xff0c;但是程序依然可以启动。 问题解决…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型

CVPR 2025 | MIMO&#xff1a;支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题&#xff1a;MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者&#xff1a;Yanyuan Chen, Dexuan Xu, Yu Hu…...

1.3 VSCode安装与环境配置

进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件&#xff0c;然后打开终端&#xff0c;进入下载文件夹&#xff0c;键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

网络编程(UDP编程)

思维导图 UDP基础编程&#xff08;单播&#xff09; 1.流程图 服务器&#xff1a;短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案

这个问题我看其他博主也写了&#xff0c;要么要会员、要么写的乱七八糟。这里我整理一下&#xff0c;把问题说清楚并且给出代码&#xff0c;拿去用就行&#xff0c;照着葫芦画瓢。 问题 在继承QWebEngineView后&#xff0c;重写mousePressEvent或event函数无法捕获鼠标按下事…...

JavaScript 数据类型详解

JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型&#xff08;Primitive&#xff09; 和 对象类型&#xff08;Object&#xff09; 两大类&#xff0c;共 8 种&#xff08;ES11&#xff09;&#xff1a; 一、原始类型&#xff08;7种&#xff09; 1. undefined 定…...

宇树科技,改名了!

提到国内具身智能和机器人领域的代表企业&#xff0c;那宇树科技&#xff08;Unitree&#xff09;必须名列其榜。 最近&#xff0c;宇树科技的一项新变动消息在业界引发了不少关注和讨论&#xff0c;即&#xff1a; 宇树向其合作伙伴发布了一封公司名称变更函称&#xff0c;因…...

[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.

ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #&#xff1a…...

HTML前端开发:JavaScript 获取元素方法详解

作为前端开发者&#xff0c;高效获取 DOM 元素是必备技能。以下是 JS 中核心的获取元素方法&#xff0c;分为两大系列&#xff1a; 一、getElementBy... 系列 传统方法&#xff0c;直接通过 DOM 接口访问&#xff0c;返回动态集合&#xff08;元素变化会实时更新&#xff09;。…...