【数据结构】时间复杂度和空间复杂度

目录

一,引言

二,时间复杂度

1,时间复杂度的概念

2,计算时间复杂度

_1,运算规则

_2运用实例:

三,空间复杂度

1,空间复杂度的概念

2,空间复杂度的计算

四,时间复杂度OJ练习:


一,引言


算法在编成一个可执行程序后,在运行时需要消耗时间资源和空间资源。由此衡量一个算法的好坏,是从时间和空间上进行衡量的。由此引出分别衡量时间和空间的时间复杂度和空间复杂度。

时间复杂度用来衡量算法执行所需要的时间。空间复杂度用来衡量算法执行时所要额外的空间。


二,时间复杂度


1,时间复杂度的概念

算法的++时间复杂度++ 本质上是一个函数,定量的描述了算法执行所要消耗的时间。算法中的++基本操作的执行次数++,就是算法的时间复杂度。

2,计算时间复杂度

_1,运算规则

上面的基本操作的执行次数为:

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

此时再通过++大O的渐进表示法++对上述式子进行处理:

大O符号:描述函数渐进行为的数学符号

步骤:

1,用常数1取代公式中的所有加法常数

2,只保留最高阶项

3,去除与最高阶项的相乘的系数

通过上述步骤后的最终时间复杂度为: O(N^2)

其中有些算法的时间复杂度存在最好,最坏,和平均的情况:

最坏情况:算法的最大运行次数(上界)

平均运行情况:算法的预期运行次数,或者将每种可能相加,最后除以N

最好情况:算法的最小运行次数(下界)

例如:在一个长度为N的数组中查找值为x的数

最好情况:1次

最坏情况:N次

平均情况:(1+2+3+......+N)/N = (N+1)/2

实际情况中使用最坏的情况,所以在数组中查找x的时间复杂度为:O(N)

_2运用实例:

常数O(1)类型:

1,

2,

N^2类型:

调用了N次,每次执行循环N,N-1,N-2......1,所以总共执行次数:1+2+3+......+N = N*(N+1)/2

故时间复杂度为:O(N^2);

log(2)n类型:

1,循环中 i<n;i *=2

2,二分查找

查找时的变化:

N/2 N/4 N/8 N/16 ......

最坏的情况:当数组中只剩下一个数或找不到时最坏

N/2/2/2/2...... = 1 -- N/(2^x) = 1

时间复杂度为2出现的次数

2^x = N x = log(2)N

时间复杂度为O(log(2)N)

2^N类型:

累计调用的结果为:2^(N-1)-1

实际次数要比求和的值小一点,原因:

由上图可知:右边先比左边先到底,所以实际会小一点

第二种方法:

总结一下,常见的时间复杂度共有以下几种情况:


三,空间复杂度

1,空间复杂度的概念

++空间复杂度++ 也是一个数学表达式,描述一个算法执行时需要++临时额外****占用的内存空间大小++。空间复杂度计算的是变量的个数。

2,空间复杂度的计算

空间复杂度的计算的关键就是计算++额外新增加的变量个数++

计算规则同样遵循大O渐进表示法:

1,用常数1取代公式中的所有加法常数

2,只保留最高阶项

3,去除与最高阶项的相乘的系数

冒泡排序:

再这个函数中只有end,exchange,i三个变量,所以空间复杂度就是:O(1)

其中形参:a,n不计入其中。

轮转数组:

核心思路:创建一个新数组,先将5,6,7拷贝到新数组当中,再将1,2,3,4拷贝到新数组当中,最后将tmp中的元素重新拷贝到nums当中

代码实现:

由于拷贝相当于将原数组中的数全部遍历一遍,所以此算法的时间复杂度为:O(N)

由于创建了一个元素个数为N的新数组,所以共创建了N个新变量,所以算法的空间复杂度为O(N)

阶乘递归的空间复杂度:

每次函数调用会开辟一个++函数栈帧++,总共调用了N次,所以总共开辟了N个栈帧,所以空间复杂度为: O(N)

常见的空间复杂度只有三个为:O(1) O(N) O(N^2)


四,时间复杂度OJ练习:

1,

解法1:先求和再减去数组元素

解法2:异或

2,

解法一:暴力求解

轮转次数:

最坏的情况是:k%numsSize=numsSize-1 --轮转n-1次

最好的情况是:k%numsSize = 0; --无需轮转

每次轮转时,要将数组中的numsSize-1个数向后整体移动一位

所以时间复杂度为:O( (N-1)*(N-1) ) = O(N^2)

时间复杂度过高,导致超出时间限制

解法2:逆置三次

代码实现:

相当于将数组当中的元素遍历了两次,所以逆置三次的时间复杂度为:O(N)

补充内容:

clock函数

头文件:#include <time.h>

核心功能:测试程序所消耗的处理器时间

返回值:返回值类型为clock_t,为一个整数,单位为毫秒

注意:下面使用int来接收也可以,方便使用%d打印。

相关推荐
ZoeJoy81 天前
算法筑基(一):排序算法——从冒泡到快排,一文掌握最经典的排序算法
数据结构·算法·排序算法
是翔仔呐1 天前
第11章 显示外设驱动:I2C协议OLED屏、SPI协议LCD屏字符/图片/中文显示
c语言·开发语言·stm32·单片机·嵌入式硬件·学习·gitee
承渊政道1 天前
【优选算法】(实战体会位运算的逻辑思维)
数据结构·c++·笔记·学习·算法·leetcode·visual studio
承渊政道1 天前
【优选算法】(实战推演模拟算法的蕴含深意)
数据结构·c++·笔记·学习·算法·leetcode·排序算法
木下~learning1 天前
对于Linux中等待队列和工作队列的讲解和使用|RK3399
linux·c语言·网络·模块化编程·工作队列·等待队列
是翔仔呐1 天前
第13章 SPI通信协议全解:底层时序、4种工作模式与W25Qxx Flash芯片读写实战
c语言·开发语言·stm32·单片机·嵌入式硬件·学习·gitee
IT方大同1 天前
RT_thread(RTOS实时操作系统)线程的创建与切换
c语言·开发语言·嵌入式硬件
历程里程碑1 天前
Protobuf 环境搭建:Windows 与 Linux 系统安装教程
linux·运维·数据结构·windows·线性代数·算法·矩阵
是翔仔呐1 天前
第14章 CAN总线通信全解:底层原理、帧结构与双机CAN通信实战
c语言·开发语言·stm32·单片机·嵌入式硬件·学习·gitee
代码探秘者1 天前
【算法】吃透18种Java 算法快速读写模板
数据结构·数据库·python·算法·spring