【数据结构】时间复杂度

目录

一、算法的复杂度

二、时间复杂度

2.1 时间复杂度的概念

2.2 大O渐进表示法

2.3 计算时间复杂度步骤

三、常见时间复杂度举例

3.1 ❥ 常数阶

3.2 ❥ 线性阶

3.3 ❥ 平方阶

3.4 ❥ 对数阶

3.5 ❥ 指数阶

3.6 ❥ 多个未知数的复杂度

四、最好,最坏,平均情况

五、时间复杂度优劣对比


一、算法的复杂度

如何衡量一个算法的好坏呢?

是从时间效率空间效率这两个方面进行衡量。

因为算法在编写成可执行程序后,运行需要耗费时间资源和空间(内存)资源。因此衡量一个算法的好坏,一般从时间和空间这两个维度来衡量。即时间复杂度和空间复杂度。

时间复杂度主要衡量一个算法的运行快慢,而空间复杂度主要衡量一个算法运行所需要的额外空间。在计算机发展的早期,计算机的存储容量很小,所以对空间的复杂度很是在乎。现如今计算机行业迅速发展,计算机存储容量很高,因此就不再特别关注算法的空间效率,通常更加注重时间效率。

注意:

        不能认为时间复杂度就比空间复杂度重要,在某些场景下空间复杂度反而比时间复杂度重要,在程序中我们需要综合考虑让时间和空间的消耗达到一个平衡点。

二、时间复杂度

2.1 时间复杂度的概念

在计算机科学中,算法的时间复杂度是一个函数,它定性描述了该算法的运行时间。

一个算法所花费的时间与其中语句的执行次数成正比例,算法中的基本操作的执行次数,为算法的时间复杂度。

例题:

int func(int n)
{
	for (int i = 0; i < n; i++)
	{
		printf("haha\n");
	}
	return 0;
}

以上代码共执行了多少次呢?

分析如下:

作为衡量代码速度的依据,当代码较多的时候,一条一条地去数就比较麻烦,而且在函数调用函数的时候,运行起来也比较麻烦。

所以,算法一般使用估算值来衡量代码的执行速度,这里用大O的渐进表示法来表示时间复杂度。

2.2 大O渐进表示法

大O渐进表示法:用来粗略度量算法的效率。

大O符号(Big O notation):是用于描述函数渐进行为的数学符号。

推导大O阶方法:

  1. 用常数1取代运行时间中的所有加法常数。
  2. 在修改后的运行次数函数中,只保留最高阶项。
  3. 如果最高阶项存在且不是1,则去除与这个项目相乘的常数,得到的结果就是大O阶。

简而言之,去掉常数项,低次幂,最高次的系数就是该函数的时间复杂度。

本质:计算算法时间复杂度(次数)属于哪个量级(level)。

使用大O的渐进表示法以后,func的时间复杂度为:O(n)

2.3 计算时间复杂度步骤


 1、找出算法中的基本语句。

        算法中执行次数最多的那条语句就是基本语句,通常是最内层循环的循环体。

 2、计算基本语句的执行次数的数量级。

  计算基本语句执行次数的数量级,这就意味着只要保证基本语句执行次数的函数中的最高次幂正确即可。

  3、用O记号表示算法的时间性能。

  将基本语句执行次数的数量级放入O记号中


三、常见时间复杂度举例

3.1 ❥ 常数阶

常数阶的时间复杂度是:O(1)

说明算法的执行时间是常量,不随输入规模的增加而增加。

例题:

//计算Print的时间复杂度
void Print()
{
	int i = 0;
	for (i = 0; i < 100; i++)
	{
		printf("lala\n");//层次最深的语句
	}
	printf("haha\n");
}

可知,最深的打印语句执行了100次,也就是常数次。用O(1)表示。

注意:

其实printf("haha\n");也算一次运算,但是它整体影响不大,(因为cpu运行速度超级快)所以可以忽略这些细枝末节,不用计算。

易错提醒:

  • O(1)是代表的是常数次,不是1次。
  • 只要是常数,都用O(1)进行表示。

3.2 ❥ 线性阶

线性阶的时间复杂度是:O(N)

例题:

// 计算阶乘递归Fac的时间复杂度
long long Fac(int N)
{
	if (0 == N)
		return 1;
	return Fac(N - 1) * N;
}

分析如下:

由此可知:

递归的时间复杂度:所有递归调用的次数累加

3.3 ❥ 平方阶

平方阶的时间复杂度是:O(N^2)

例题:

// 计算阶乘递归Fac的时间复杂度
long long Fac(int N)
{
	if (0 == N)
		return 1;

	for (int i = 0; i < n; ++i)
	{
		//...
	}

	return Fac(N - 1) * N;
}

分析如下:

由于计算的是算法时间复杂度(次数)属于哪个量级,所以只需要看决定性的项,也就是最高阶的项,不需要关注那些细枝末节。

所以(n^2+n)/2属于平方阶,忽略它的最高项的系数以及低次项,因此算出来的该递归函数的时间复杂度为O(N^2)。

3.4 ❥ 对数阶

对数阶的时间复杂度是:O(logN)

例题:

// 计算BinarySearch的时间复杂度
int BinarySearch(int* a, int n, int x)
{
	assert(a);
	int begin = 0;
	int end = n - 1;
	while (begin <= end)
	{
		int mid = begin + ((end - begin) >> 1);
		if (a[mid] < x)
			begin = mid + 1;
		else if (a[mid] > x)
			end = mid - 1;
		else
			return mid;
	}
	return -1;
}

分析如下:

3.5 ❥ 指数阶

指数阶的时间复杂度是:O(2^N)

例题:

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

分析如下:

3.6 ❥ 多个未知数的复杂度

一个时间复杂度里面也不一定只有一个未知数。

那遇见存在多个未知数的情况,我们该如何写代码呢?

我们举例来说明,看如下代码:

// 计算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);
}

分析如下:

该代码的时间复杂度为:O(M+N)

也可以写成O(max(M,N))

如果有说明M和N的关系的,写成下面的形式这样更好

  1. 若M远大于N:O(M)
  2. 若N远大于M:O(N)

四、最好,最坏,平均情况

算法的复杂度存在最好,最坏,和平均情况

  • 最坏情况:任意输入规模的最多运行次数(上界)
  • 平均情况:任意输入规模的期望运行次数
  • 最好情况:任意输入规模的最少运行次数(下界)

例如:在一个长度为N数组中搜索一个数据x

最好的情况:1次找到

最坏的情况:N次找到

平均情况:N/2次找到

我们在实际中一般情况关注的是算法的最坏运行情况(也就是最低的预期),所以数组中搜索数据时间复杂度为O(N)。

五、时间复杂度优劣对比

常见的数量级大小:越小表示算法的执行时间频度越短,则越优。(时间复杂度越,效率越

O(1) < O(logn) < O(n) < O(nlogn) < O(n2) < O(2n) < O(n!)

速记:常对幂指阶(时间复杂度:低——>高)

所以, 我们编写代码时一定要注意时间复杂度的级别控制,养成良好的代码编写习惯。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

人工智能机器学习算法总结偏差和方差

1.定义 在机器学习中&#xff0c;偏差&#xff08;Bias&#xff09;和方差&#xff08;Variance&#xff09;是评估模型泛化能力的重要概念。它们描述了模型在训练数据上的表现以及对新数据的适应能力。 偏差&#xff08;Bias&#xff09; &#xff1a; 偏差是指模型的预测值与…

SARscape下载DEM进度条不动的问题

使用SARscape的DEM Extraction下载DEM&#xff0c;进度条不动问题的解决办法&#xff1a; 一个字&#xff1a; 我是等了一晚上&#xff0c;第二天就好了。下载的DEM范围是一景SAR影像&#xff0c;未裁剪。

Java研学-RBAC权限控制(八)

九 登录登出 1 登录作用 判断员工是否有权限访问&#xff0c;首先得知道现在操作的人是谁&#xff0c;所以必须先实现登录功能 2 登录流程 ① 提供登录页面&#xff0c;可输入用户名与密码信息&#xff0c;并添加执行登录的按钮。&#xff08;登录页面不能被拦截&#xff09;…

java之SSRF代码审计

1、SSRF漏洞审计点 服务端请求伪造&#xff08;Server-Side Request Forge&#xff09;简称 SSRF&#xff0c;它是由攻击者构造的 payload传给服务端&#xff0c;服务端对传回的 payload 未作处理直接执行后造成的漏洞&#xff0c;一般用于在内网探测或攻击内网服务。 利用&a…

捕捉过往的时光,5个步骤,安卓手机找回删除的照片

手机不仅仅是一个通讯工具&#xff0c;更是一个记录生活点滴的神器。手机照相机的出现&#xff0c;让我们随时随地都能捕捉到美好的瞬间&#xff0c;留下珍贵的回忆。然而&#xff0c;随着时间的推移&#xff0c;我们可能会不小心删除了这些照片&#xff0c;或者因为各种原因导…

分布式锁实现方案-基于Redis实现的分布式锁

目录 一、基于Lua看门狗实现 1.1 缓存实体 1.2 延迟队列存储实体 1.3 分布式锁RedisDistributedLockWithDog 1.4 看门狗线程续期 1.5 测试类 1.6 测试结果 1.7 总结 二、RedLock分布式锁 2.1 Redlock分布式锁简介 2.2 RedLock测试例子 2.3 RedLock 加锁核心源码分析…

DVWA-CSRF-samesite分析

拿DVWA的CSRF为例子 接DVWA的分析&#xff0c;发现其实Impossible的PHPSESSID是设置的samesite1. 参数的意思参考Set-Cookie SameSite:控制 cookie 是否随跨站请求一起发送&#xff0c;这样可以在一定程度上防范跨站请求伪造攻击&#xff08;CSRF&#xff09;。 下面用DVWA CS…

springboot加载bean的方式

在SpringBoot的大环境下&#xff0c;基本上很少使用之前的xml配置Bean&#xff0c;主要是因为这种方式不好维护而且也不够方便。 springboto注入bean主要采用下图几种方式&#xff0c; 1、注解装配Bean 1、使用Component等派生注解 只要在类上加类上加 Component 注解即可,该…

[图解]企业应用架构模式2024新译本讲解17-活动记录1

1 00:00:01,070 --> 00:00:04,180 下一个我们要说的就是 2 00:00:04,190 --> 00:00:06,740 活动记录模式了 3 00:00:07,640 --> 00:00:11,210 同样是数据源架构模式 4 00:00:12,300 --> 00:00:18,480 里面的一个&#xff0c;活动记录 5 00:00:18,490 --> 00…

万界星空科技低代码云mes核心功能详解!建议收藏!

在当今数字化时代&#xff0c;制造企业面临着日益复杂的生产管理挑战。为了提高生产效率、降低成本、优化资源利用&#xff0c;许多企业开始转向云端制造执行系统&#xff08;MES&#xff09;。云MES系统作为数字化转型的关键组成部分&#xff0c;具有一系列核心功能和优势&…

Maven深度解析:Java项目构建

Maven是一个由Apache软件基金会维护的软件项目管理和理解工具&#xff0c;它主要服务于基于Java的软件项目。。 Maven深度解析&#xff1a;Java项目构建 引言 在Java开发领域&#xff0c;项目构建和管理是一个复杂而关键的任务。Maven作为这一领域的佼佼者&#xff0c;以其声…

MySQL的综合运用

MySQL版的葵花宝典&#xff0c;欲练此功&#xff0c;挥刀自。。。呃&#xff0c;&#xff0c;&#xff0c;说错了&#xff0c;是先创建两个表&#xff0c;分别是location表和store_info表 示例表为location表和store_info表&#xff0c;如下图所示&#xff1a; 操作一&#xf…

OpenAI Sora:我们来自混乱,我们也将回归混乱

最近&#xff0c;我开始深入了解并整理一些关于Sora这个人工智能模型的系列文章。我的目标是从两个角度深入探讨&#xff1a;一是Sora的技术细节&#xff0c;包括它的原理和功能&#xff1a;OpenAI Sora&#xff1a;距离黑客帝国仅一步之遥&#xff0c;二是Sora的应用前景&…

告别繁琐!一键互换新旧文件夹名,高效批量改名神器助您轻松管理文件库

在日常工作中&#xff0c;我们经常需要对文件夹进行命名和重命名操作。然而&#xff0c;当面对大量需要互换新旧名称的文件夹时&#xff0c;传统的手动操作不仅效率低下&#xff0c;还容易出错。为了解决这一难题&#xff0c;我们特别推出了一款高效、便捷的文件夹批量改名工具…

【GD32F303红枫派使用手册】第二十四节 DHT11温湿度传感器检测实验

24.1 实验内容 通过本实验主要学习以下内容&#xff1a; DHT11操作原理 单总线GPIO模拟操作原理 24.2 实验原理 HT11是一款已校准数字信号输出的温湿度一体化数字传感器。该产品具有品质卓越、超快响应、抗干扰能力强、性价比极高等优点信号&#xff0c;传输距离可达20米以…

nginx负载均衡案例,缓存知识----补充

负载均衡案例 ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near great all on wordpress.* to wp172.16.1.% indentified by 1 at line 1 MariaDB [(none)]>…

算法与数据结构面试宝典——回溯算法详解(C#,C++)

文章目录 1. 回溯算法的定义及应用场景2. 回溯算法的基本思想3. 递推关系式与回溯算法的建立4. 状态转移方法5. 边界条件与结束条件6. 算法的具体实现过程7. 回溯算法在C#&#xff0c;C中的实际应用案例C#示例C示例 8. 总结回溯算法的主要特点与应用价值 回溯算法是一种通过尝试…

算法常见手写代码

1.NMS def py_cpu_nms(dets, thresh):"""Pure Python NMS baseline."""#x1、y1、x2、y2、以及score赋值x1 dets[:, 0]y1 dets[:, 1]x2 dets[:, 2]y2 dets[:, 3]scores dets[:, 4]#每一个检测框的面积areas (x2 - x1 1) * (y2 - y1 1)#按…

C语言 while循环1

在C语言里有3种循环&#xff1a;while循环 do while 循环 for循环 while语句 //while语法结构 while&#xff08;表达式&#xff09;循环语句; 比如在屏幕上打印1-10 在while循环中 break用于永久的终止循环 在while循环中&#xff0c;continue的作用是跳过本次循环 …