【数据结构】算法效率的双刃剑:时间复杂度与空间复杂度

前言

在算法的世界里,效率是衡量算法优劣的关键标准。今天,就让我们深入探讨算法效率的两个核心维度:时间复杂度和空间复杂度,帮助你在算法设计的道路上更进一步。

一、算法效率:衡量算法好坏的关键

算法的效率主要体现在两个方面:时间和空间。时间复杂度衡量的是算法运行的快慢,而空间复杂度则衡量算法运行所需的额外空间。在计算机发展的早期,存储容量有限,空间复杂度备受关注。然而,随着计算机存储容量的飞速发展,如今我们更关注算法的时间复杂度。

1.1 斐波那契数列:一个经典的例子

斐波那契数列是一个经典的算法问题。其递归实现方式简洁明了,但这种简洁性是否意味着它是一个好的算法呢?答案并非绝对。递归实现虽然代码简洁,但其时间复杂度较高,对于较大的输入值,运行时间会显著增加。这正是我们需要深入分析算法复杂度的原因。

long long Fib(int N)
{if (N < 3)return 1;return Fib(N - 1) + Fib(N - 2);
}

二、时间复杂度:算法运行快慢的量化

时间复杂度是衡量算法运行时间的函数。它通过分析算法中基本操作的执行次数来确定。在实际中,我们通常使用大O的渐进表示法来简化复杂度的表达。

2.1 大O的渐进表示法

大O符号(Big O notation)是描述函数渐进行为的数学符号。推导大O阶的方法如下:
用常数1取代运行时间中的所有加法常数。
在修改后的运行次数函数中,只保留最高阶项。
如果最高阶项存在且不是1,则去除与这个项目相乘的常数。
例如,对于以下代码:

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--){++count;}
}

通过计算,我们发现基本操作++count的执行次数为 N^ 2+2*N+10。使用大O的渐进表示法,我们去掉常数项和低阶项,得到时间复杂度为 O(N ^2 )。

2.2 常见时间复杂度计算举例

让我们通过一些实例来进一步理解时间复杂度的计算。

实例1

void Func2(int N)
{int count = 0;for (int k = 0; k < 2 * N; ++k){++count;}int M = 10;while (M--){++count;}
}

基本操作执行了 2N+10 次,时间复杂度为 O(N)。

实例2

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;}
}

基本操作执行了 M+N 次,时间复杂度为 O(N+M)。

实例3

void Func4(int N)
{int count = 0;for (int k = 0; k < 100; ++k){++count;}
}

基本操作执行了10次,时间复杂度为 O(1)。(O(1)不是代表一次,而是代表常数次)

实例4

const char *strchr(const char *str, int character);while(*str)
{if(*str == character)return str;str++;

在这里插入图片描述

时间复杂度为 O(N)。(一般以最坏情况作为时间复杂度)

实例5

void BubbleSort(int *a, int n)
{assert(a);for (size_t end = n; end > 0; --end){int exchange = 0;for (size_t i = 1; i < end; ++i){if (a[i - 1] > a[i]){Swap(&a[i - 1], &a[i]);exchange = 1;}}if (exchange == 0)break;}
}

时间复杂度为 O(N^2 )。(最好:O(N),最坏:O(N ^ 2))

实例6(有序 经典二分查找)

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;elsereturn mid;}return -1;
}

时间复杂度为 O(logN)。(最好:O(1),最坏:O(logN)区间缩放到一个值时,要么找到,要么找不到,折半查找多少次(x)就除多少个2。2^x=N

三、空间复杂度:算法所需额外空间的量化

空间复杂度是对一个算法在运行过程中临时占用存储空间大小的量度。它主要通过函数在运行时显式申请的额外空间来确定。

3.1 空间复杂度计算实例

实例1

long long Fac(size_t N)
{if (0 == N)return 1;return Fac(N - 1) * N;
}
Fac(N)
Fac(N-1)
Fac(N-2)
...
Fac(1)
Fac(0)

空间复杂度为 O(N)。

实例2

long long *Fibonacci(size_t n)
{if (n == 0)return NULL;long long *fibArray = (long long *)malloc((n + 1) * sizeof(long long));fibArray[0] = 0;fibArray[1] = 1;for (int i = 2; i <= n; ++i){fibArray[i] = fibArray[i - 1] + fibArray[i - 2];}return fibArray;
}

空间复杂度为 O(N)。

实例3

long long Fib(size_t N)
{if (N < 3)return 1;return Fib(N - 1) + Fib(N - 2);
}
   2^0  Fib(N)2^1Fib(N-1)  Fib(N-2)2^2 Fib(N-2) Fib(N-3)  Fib(N-3) Fib(N-2)...2^(N-1)Fib(2)  Fib(1)

空间复杂度为 O(2^N)。

四、常见复杂度对比

常见的复杂度从低到高依次为:O(1)、O(logN)、O(N)、O(NlogN)、O(N^2 )、O(2 ^N )、O(N!)。选择合适的算法,可以显著提升程序的运行效率。
在这里插入图片描述
在这里插入图片描述

五、复杂度的OJ练习

理论学习之后,通过实践来巩固知识是必不可少的。以下是一些推荐的OJ题目:
消失的数字
参考:
1.
在这里插入图片描述
2.
在这里插入图片描述

旋转数组

总结

时间复杂度和空间复杂度是算法设计中不可或缺的两个维度。通过深入理解它们,我们可以更好地选择和设计高效的算法。希望这篇文章能帮助你更好地掌握算法效率的分析方法,让你在算法学习的道路上更进一步。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java基础-26-多态-认识多态

在Java编程中&#xff0c;多态&#xff08;Polymorphism&#xff09; 是面向对象编程的核心概念之一。通过多态&#xff0c;我们可以编写更加灵活、可扩展的代码。本文将详细介绍什么是多态、如何实现多态&#xff0c;并通过具体的例子来帮助你更好地理解这一重要概念。 一、什…

使用自定义的RTTI属性对对象进行流操作

由于历史原因&#xff0c;在借鉴某些特定出名的游戏引擎中&#xff0c;不知道当时的作者的意图和编写方式 特此做这篇文章。&#xff08;本文出自游戏编程精粹4 中 使用自定义的RTTI属性对对象进行流操作 文章&#xff09; 载入和 保存 关卡&#xff0c;并不是一件容易办到的事…

周总结aa

上周学习了Java中有关字符串的内容&#xff0c;与其有关的类和方法 学习了static表示静态的相关方法和类的使用。 学习了继承(extends) 多态&#xff08;有继承关系&#xff0c;有父类引用指向子类对象&#xff09; 有关包的知识&#xff0c;final关键字的使用&#xff0c;及有…

密码学基础——密码学相关概念

目录 1.1 密码系统&#xff08;Cryptosystem&#xff09; 1.2 密码编码学 1.3 密码分析学 1.4 基于算法保密 1.5 基于密钥保密 1.6密码系统的设计要求 1.7 单钥体制 1.8 双钥体制 密钥管理 1.1 密码系统&#xff08;Cryptosystem&#xff09; 也称为密码体制&#xff0…

初始JavaEE篇 —— Mybatis-plus 操作数据库

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a;JavaEE 目录 前言 Mybatis-plus 快速上手 Mybatis-plus 复杂操作 常用注解 TableName TableField TableId 打印日志 条件构造器 …

PyQt6实例_批量下载pdf工具_主线程启用线程池

目录 前置&#xff1a; 代码&#xff1a; 视频&#xff1a; 前置&#xff1a; 1 本系列将以 “PyQt6实例_批量下载pdf工具”开头&#xff0c;放在 【PyQt6实例】 专栏 2 本系列涉及到的PyQt6知识点&#xff1a; 线程池&#xff1a;QThreadPool,QRunnable&#xff1b; 信号与…

1.2 斐波那契数列模型:LeetCode 面试题 08.01. 三步问题

动态规划解三步问题&#xff1a;LeetCode 面试题 08.01. 三步问题 1. 题目链接 LeetCode 面试题 08.01. 三步问题 题目要求&#xff1a;小孩上楼梯&#xff0c;每次可以走1、2或3步&#xff0c;计算到达第 n 阶台阶的不同方式数&#xff0c;结果需对 1e9 7 取模。 2. 题目描述…

UE5 学习笔记 FPS游戏制作30 显示击杀信息 水平框 UI模板(预制体)

文章目录 一制作单条死亡信息框水平框的使用创建一个水平框添加子元素调整子元素顺序子元素的布局插槽尺寸填充对齐 制作UI 根据队伍&#xff0c;设置文本的名字和颜色声明变量 将变量设置为构造参数根据队伍&#xff0c;设置文本的名字和颜色在构造事件中&#xff0c;获取玩家…

HTTP---基础知识

天天开心&#xff01;&#xff01;&#xff01; 文章目录 一、HTTP基本概念1. 什么是HTTP&#xff0c;又有什么用&#xff1f;2. 一次HTTP请求的过程3.HTTP的协议头4.POST和GET的区别5. HTTP状态码6.HTTP的优缺点 二、HTTP的版本演进1.各个版本的应用场景2、注意要点 三、HTTP与…

数据结构 KMP 字符串匹配算法

KMP算法是计算机科学中的一种字符串匹配算法&#xff0c;KMP是三个创始人名字首字母 题目 AcWing - 算法基础课 前置知识点 KMP算法是一种高效的字符串匹配算法&#xff0c;算法名称取自于三位共同发明人名字的首字母组合。该算法的主要使用场景就是在字符串&#xff08;也叫…

Conda配置Python环境

1. 安装 Conda 选择发行版&#xff1a; Anaconda&#xff1a;适合需要预装大量科学计算包的用户&#xff08;体积较大&#xff09;。 Miniconda&#xff1a;轻量版&#xff0c;仅包含 Conda 和 Python&#xff08;推荐自行安装所需包&#xff09;。 验证安装&#xff1a; co…

数仓开发那些事(11)

某神州优秀员工&#xff1a;一闪&#xff0c;领导说要给我涨米。 一闪&#xff1a;。。。。&#xff08;着急的团团转&#xff09; 老运维&#xff1a;Oi&#xff0c;两个吊毛&#xff0c;看看你们的hadoop集群&#xff0c;健康度30分&#xff0c;怎么还在抽思谋克&#xff1f…

MyBatis Plus 中 update_time 字段自动填充失效的原因分析及解决方案

✅ MyBatis Plus 中 update_time 字段自动填充失效的原因分析及解决方案 前言一、问题现象二、原因分析1. 使用了 strictInsertFill/strictUpdateFill 导致更新失效2. 实体类注解配置错误3. MetaObjectHandler 未生效4. 使用自定义 SQL 导致自动填充失效5. 字段类型不匹配 三、…

C++ STL常用算法之常用算术生成算法

常用算术生成算法 学习目标: 掌握常用的算术生成算法 注意: 算术生成算法属于小型算法&#xff0c;使用时包含的头文件为 #include <numeric> 算法简介: accumulate // 计算容器元素累计总和 fill // 向容器中添加元素 accumulate 功能描述: 计算区间内容器元素…

axios基础入门教程

一、axios 简介 axios 是一个基于 Promise 的 HTTP 客户端&#xff0c;可用于浏览器和 Node.js 环境&#xff0c;支持以下特性&#xff1a; 发送 HTTP 请求&#xff08;GET/POST/PUT/DELETE 等&#xff09; 拦截请求和响应 自动转换 JSON 数据 取消请求 并发请求处理 二…

短视频团队架构工作流程---2025.3.30 李劭卓

短视频团队架构&工作流程—2025.3.30 李劭卓 文章目录 短视频团队架构&工作流程---2025.3.30 李劭卓1 工作职责1.1 编剧&#xff1a;1.2 主编&#xff1a;1.3 总编&#xff1a;1.4 导演&#xff1a;1.5 摄影&#xff1a;1.6 演员&#xff1a;1.7 后期&#xff1a;1.8 美…

MySQL 高效 SQL 使用技巧详解

MySQL 高效 SQL 使用 技巧详解 一、为什么需要优化 SQL&#xff1f; 性能瓶颈&#xff1a;慢查询导致数据库负载升高&#xff0c;响应时间延长。资源浪费&#xff1a;低效 SQL 可能占用大量 CPU、内存和磁盘 I/O。 目标&#xff1a;通过优化 SQL 将查询性能提升 10 倍以上&am…

AI基础03-视频数据采集

上篇文章我们学习了图片的数据采集&#xff0c;今天主要了解一下视频数据采集的方法。视频是由一系列图像构成的&#xff0c;其中每一张图片就是一帧。视频数据采集方法通常有自动图像采集和基于处理器的图像采集两种。我们学习一下如何利用python 工具和笔记本计算机摄像头进行…

Scala 数组

Scala 数组 引言 Scala 作为一门多范式编程语言&#xff0c;融合了面向对象和函数式编程的特点。数组是编程语言中非常基础和常见的数据结构&#xff0c;在 Scala 中也不例外。本文将详细介绍 Scala 中的数组&#xff0c;包括其定义、操作以及在实际开发中的应用。 Scala 数…

Text-to-SQL将自然语言转换为数据库查询语句

有关Text-To-SQL方法&#xff0c;可以查阅我的另一篇文章&#xff0c;Text-to-SQL方法研究 直接与数据库对话-text2sql Text2sql就是把文本转换为sql语言&#xff0c;这段时间公司有这方面的需求&#xff0c;调研了一下市面上text2sql的方法&#xff0c;比如阿里的Chat2DB,麻…