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

目录

一,引言

二,时间复杂度

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打印。

相关推荐
爱编码的小八嘎17 分钟前
C语言完美演绎8-4
c语言
故事和你912 小时前
洛谷-数据结构-1-3-集合3
数据结构·c++·算法·leetcode·贪心算法·动态规划·图论
自我意识的多元宇宙2 小时前
二叉树的遍历和线索二叉树--线索二叉树
数据结构
菜鸟丁小真3 小时前
LeetCode hot100-287.寻找重复数和994.腐烂的橘子
数据结构·算法·leetcode·知识点总结
零号全栈寒江独钓3 小时前
基于c/c++实现linux/windows跨平台ntp时间戳服务器
linux·c语言·c++·windows
笨鸟先飞的橘猫3 小时前
数据结构学习——跳表
数据结构·python·学习
Pentane.4 小时前
【力扣hot100】【Leetcode 15】三数之和|暴力枚举 双指针 算法笔记及打卡(14/100)
数据结构·笔记·算法·leetcode
Mr_pyx4 小时前
【LeetCode Hot 100】 - 缺失的第一个正数完全题解
数据结构·算法
xieliyu.4 小时前
Java顺序表实现扑克牌Fisher-Yates 洗牌算法
java·数据结构·算法·javase
guygg884 小时前
极化码(Polar Codes)的MATLAB实现
开发语言·数据结构·matlab