【数据结构与算法】算法优化、时间复杂度、空间复杂度

文章目录

  • 一、什么是复杂度?
  • 二、大O表示法
  • 三、时间复杂度计算
  • 四、常见复杂度的比较
  • 五、算法优化的核心方法论
  • 六、常见算法复杂度
  • 五、总结


一、什么是复杂度?

复杂度是衡量代码运行效率的重要的度量因素。 而复杂度主要就是指时间复杂度和空间复杂度

首先,时间复杂度的计算并不是计算程序具体运行的时间,而是算法执行语句的次数。当我们面前有多个算法时,我们可以通过计算时间复杂度,判断出哪一个算法在具体执行时花费时间最多和最少。
空间复杂度则是对一个算法在运行过程中临时占用电脑存储空间大小的量度。

在过去,由于计算机性能低下,系统存储空间很小,这种情况下,降低空间的损耗就极其重要了!所以,在这种情况下,程序员要考虑的就是尽可能的降低空间复杂度。

但是,时间复杂度和空间复杂度往往是相对的。降低空间消耗的代价就是增加时间。

而现在,硬件技术发展迅速,在强大的硬件支持下,存储空间已经不是困扰人们的问题了。这种情况下,人们要求的是更快的运行速率。再加上现在大数据盛行。牺牲廉价的空间来换取宝贵的时间就很有必要了!

所以,我们现在研究的是:如何用算法有效的降低时间复杂度!

好,现在我们已经了解了复杂度的作用,那应该如何去计算复杂度呢?

二、大O表示法

复杂度是一个关于输入数据量 n 的函数。
假设你的代码复杂度是 f(n),那么就用个大写字母 O 和括号,把 f(n) 括起来就可以了,即 O(f(n))。例如,O(n) 表示的是,复杂度与计算实例的个数 n 线性相关;O(logn) 表示的是,复杂度与计算实例的个数 n 对数相关。
通常,复杂度的计算方法遵循以下几个原则:

  • 首先,复杂度与具体的常系数无关,例如 O(n) 和 O(2n) 表示的是同样的复杂度。我们详细分析下,O(2n) 等于O(n+n),也等于 O(n) + O(n)。也就是说,一段 O(n) 复杂度的代码只是先后执行两遍 O(n),其复杂度是一致的。
  • 其次,多项式级的复杂度相加的时候,选择高者作为结果,例如 O(n²)+O(n) 和 O(n²)表示的是同样的复杂度。具体分析一下就是,O(n²)+O(n) = O(n²+n)。随着 n越来越大,二阶多项式的变化率是要比一阶多项式更大的。因此,只需要通过更大变化率的二阶多项式来表征复杂度就可以了。

值得一提的是,O(1) 也是表示一个特殊复杂度,含义为某个任务通过有限可数的资源即可完成。此处有限可数的具体意义是,与输入数据量 n 无关。

三、时间复杂度计算

  • 常数阶
int i;for (i = 0; i < 100; i++){/ * * /}

这里只循环100次。不随着输入数据量 n 增加而增长,所以,此类算法的时间复杂度是O(1)。

  • 线性阶
int i;for (i = 0; i < n; i++){/ * * /}

它是一个 for 循环,时间复杂度为 O(n) , 因为循环体中的代码须要执行n次。

  • 对数阶
int count = 1;
while (count < n){
count = count * 2;
/*  */
}

由于每次 count 乘以 2 之后,就距离 n 更近了一分。 也就是说,有多少个 2 相乘后大于 n ,则会退出循环。由 2^x=n 得到x=log2(n) 。 所以这个循环的时间复杂度为O(log(n)) 。

  • 平方阶
int i , j ;for (i = 0; i < n; i++){for ( j = 0 ; j < n ; j++ ){/*  */}}

而对于外层的循环,不过是内部这个时间复杂度为 O(n)的语句,再循环 n 次 。 所以这段代码的时间复杂度为 O(n^2)。
如果外循环的循环次数改为了m, 时间复杂度就变为 O(m×n)。

int i , j ;for (i = 0; i < m; i++){for ( j = 0 ; j < n ; j++ ){/*  */}}

所以我们可以总结得出,循环的时间复杂度等于循环体的复杂度乘以该循环运行的次数。

四、常见复杂度的比较

常见的时间复杂度有:
常数阶O(1),
对数阶O(log2 n),
线性阶O(n),
线性对数阶O(n log2 n),
平方阶O(n^2),
立方阶O(n^3)
k次方阶O(n^K),
指数阶O(2^n)。

随着n的不断增大,时间复杂度不断增大,算法花费时间越多。
在这里插入图片描述
为了更好理解,我们来看一些数据。假设某个计算任务需要处理 10万 条数据。你编写的代码:

  • 如果是 O(n²) 的时间复杂度,那么计算的次数就大概是 100 亿次左右。
  • 如果是 O(n),那么计算的次数就是 10万 次左右。
  • 如果这个工程师再厉害一些,能在 O(log n) 的复杂度下完成任务,那么计算的次数就是 17 次左右(log 100000 =16.61,计算机通常是二分法,这里的对数可以以 2 为底去估计)。
  • 而O(1)是固定次数的计算,如:计算任务需要处理 10万 条数据,它是计算100次; 计算任务需要处理 10 条数据,它是还计算100次; 所以并不能和其他O(log n), O(n),O(n²) 混为一谈!
    在这里插入图片描述

五、算法优化的核心方法论

  • 第一步,暴力解法。在没有任何时间、空间约束下,完成代码任务的开发。
  • 第二步,无效操作处理。将代码中的无效计算、无效存储剔除,降低时间或空间复杂度。
  • 第三步,时空转换。设计合理数据结构,完成时间复杂度向空间复杂度的转移。

第一步暴力解法没有太多的套路,只要围绕你面临的问题出发,大胆发挥想象去尝试解决即可。

第二步无效操作处理中,你需要学会并掌握递归、二分法、排序、动态规划等常用的算法思维。通过各种算法将代码中的无效计算(冗余时间)、无效存储(冗余空间)剔除,降低时间或空间复杂度。

第三步时空转换,你需要对数据的操作进行细分,全面掌握常见数据结构的基础知识。再围绕问题,有针对性的设计数据结构、采用合理的算法思维,去不断完成时空转移,用空间换取时间,降低时间复杂度。

六、常见算法复杂度

在这里插入图片描述

算法/排序时间复杂度空间复杂度
线性查找(Linear Search)最好情况 O(1),平均情况 O(n),最坏情况 O(n)O(1)
二分查找(Binary Search)最好情况 O(1),平均情况 O(log n),最坏情况 O(log n)O(1)
冒泡排序(Bubble Sort)最好情况 O(n),平均情况 O(n^2),最坏情况 O(n^2)O(1)
快速排序(Quick Sort)最好情况 O(n log n),平均情况 O(n log n),最坏情况 O(n^2)最好情况 O(log n),平均情况 O(log n),最坏情况 O(n)
堆排序(Heap Sort)最好情况 O(n log n),平均情况 O(n log n),最坏情况 O(n log n)O(1)
插入排序(Insertion Sort)最好情况 O(n),平均情况 O(n^2),最坏情况 O(n^2)O(1)
选择排序(Selection Sort)最好情况 O(n^2),平均情况 O(n^2),最坏情况 O(n^2)O(1)
归并排序(Merge Sort)最好情况 O(n log n),平均情况 O(n log n),最坏情况 O(n log n)O(n)
希尔排序(Shell Sort)最好情况取决于增量序列,平均情况取决于增量序列,最坏情况取决于增量序列O(1)
布隆过滤器(Bloom Filter)插入和查询都是 O(k),其中 k 是哈希函数的数量取决于哈希函数数量和位数组大小
动态规划(Dynamic Programming)根据问题而定,通常在 O(n^2) 到 O(n^3) 之间根据问题而定,通常在 O(n) 到 O(n^2) 之间
KMP 算法(Knuth-Morris-Pratt Algorithm)O(m + n),其中 m 是模式串长度,n 是文本串长度O(m),其中 m 是模式串长度
Prim 算法(Minimum Spanning Tree)O(V^2) 或 O(E log V),V 是顶点数,E 是边数O(V) 或 O(E),取决于具体实现方式
Kruskal 算法(Minimum Spanning Tree)O(E log E),E 是边数O(E)
贪心算法(Greedy Algorithm)根据问题而定,通常在 O(n log n) 到 O(n^2) 之间O(1) 或 O(n),取决于具体实现方式
拓扑排序算法(Topological Sorting)O(V + E),其中 V 是顶点数,E 是边数O(V)
Dijkstra 算法(Shortest Path)O(V^2) 或 O(E log V),V 是顶点数,E 是边数O(V^2) 或 O(VE),取决于具体实现方式
Bellman-Ford 算法(Shortest Path)O(VE),V 是顶点数,E 是边数O(VE)
Floyd-Warshall 算法(Shortest Path)O(V^3),V 是顶点数O(V^2)
Boyer-Moore 算法(String Matching)最坏情况下 O(mn),其中 m 是模式串长度,n 是文本串长度O(m),其中 m 是模式串长度
哈希表(Hash Table)插入、查找、删除操作平均情况下为 O(1),最坏情况下为 O(n)取决于哈希表大小和存储的元素数量
最大子序列和问题(Maximum Subarray Problem)O(n),其中 n 是数组的长度O(1)
括号匹配问题(Parentheses Matching Problem)O(n),其中 n 是字符串的长度O(n)
深度学习算法(Deep Learning Algorithms)取决于神经网络的结构和训练数据量取决于神经网络的参数数量和层数
布隆过滤器(Bloom Filter)插入和查询操作都是 O(k),其中 k 是哈希函数的数量取决于哈希函数数量和位数组大小
Rabin-Karp 字符串匹配算法平均情况下为 O(n + m),最坏情况下为 O(nm)O(1)
RSA 公钥加密算法取决于素数的大小和加密数据的长度O(1)
哈夫曼编码(Huffman Coding)O(n log n),其中 n 是字符集的大小取决于字符集的大小和编码长度
最长公共子序列(Longest Common Subsequence)O(mn),其中 m 和 n 分别是两个字符串的长度O(mn)
最大流算法(Max Flow Algorithm)O(V * E^2),其中 V 是顶点数,E 是边数O(V^2)
最大子数组问题(Maximum Subarray Problem)O(n),其中 n 是数组的长度O(1)
拓扑排序算法(Topological Sorting)O(V + E),其中 V 是顶点数,E 是边数O(V)
最短路径算法(Shortest Path Algorithms)Dijkstra 算法:O(V^2) 或 O(E log V)
Bellman-Ford 算法:O(VE)
Floyd-Warshall 算法:O(V^3)
O(V^2) 或 O(VE)
最小生成树算法(Minimum Spanning Tree Algorithms)Prim 算法:O(V^2) 或 O(E log V)
Kruskal 算法:O(E log E)
O(V) 或 O(E)
贪心算法(Greedy Algorithm)根据问题而定,通常在 O(n log n) 到 O(n^2) 之间O(1) 或 O(n)

五、总结

OK,今天的内容到这儿就结束了。相信你对复杂度的概念有了进一步的认识。总结一下:

程序优化、算法优化、时间复杂度和空间复杂度优化是提高程序性能和效率的关键。程序优化是指通过改进代码结构、算法、数据结构等方面来提高程序的运行速度和资源利用率。算法优化则是针对特定问题设计更高效的算法,以减少计算时间和资源消耗。时间复杂度是衡量算法执行时间的指标,通常用大O符号表示,优化算法可以降低时间复杂度。空间复杂度是衡量算法内存消耗的指标,优化算法可以降低空间复杂度。综上所述,通过程序优化、算法优化、时间复杂度和空间复杂度优化可以使程序更加高效和节约资源。

  1. 程序优化

    • 优化代码结构,消除冗余和重复代码,提高代码可读性和维护性。
    • 使用高效的数据结构和算法,避免不必要的循环和操作。
    • 减少内存分配和释放次数,避免内存泄漏和频繁的内存操作。
  2. 算法优化

    • 选择合适的算法来解决问题,比如排序、查找、图算法等。
    • 优化算法的实现,减少不必要的计算和操作。
    • 考虑特定问题的特点,设计针对性的算法来提高效率。
  3. 时间复杂度优化

    • 分析算法的时间复杂度,选择具有更低时间复杂度的算法。
    • 避免嵌套循环和递归调用,优化算法的执行路径。
    • 尽量减少不必要的计算和操作,提高算法的执行效率。
  4. 空间复杂度优化

    • 分析算法的空间复杂度,选择具有更低空间复杂度的算法。
    • 使用合适的数据结构来减少内存消耗,比如使用数组代替链表。
    • 及时释放不再需要的内存,避免内存泄漏和内存碎片化。

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

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

相关文章

算法思想总结:哈希表

一、哈希表剖析 1、哈希表底层&#xff1a;通过对C的学习&#xff0c;我们知道STL中哈希表底层是用的链地址法封装的开散列。 2、哈希表作用&#xff1a;存储数据的容器&#xff0c;插入、删除、搜索的时间复杂度都是O&#xff08;1&#xff09;&#xff0c;无序。 3、什么时…

低功耗蓝牙模块在便携式医疗设备上的应用前景

随着科技的不断发展&#xff0c;医疗设备的便携性和智能化已经成为了一种趋势。在这个背景下&#xff0c;低功耗蓝牙模块(Bluetooth Low Energy,简称BLE)作为一种先进的无线通信技术&#xff0c;正逐渐在便携式医疗设备中发挥着越来越重要的作用。本文美迅物联网MesoonRF将探讨…

TiKV学习5:TiDB SQL执行流程

目录 1. DML语句读流程概要 2. DML语句写流程概要 3. DDL 流程概要 4. SQL的Parse和Compile 5. 读取的执行 6. 写入的执行 7. DDL的执行 8. 小结 1. DML语句读流程概要 TiDB Server接收sql并处理&#xff0c;TiKV负责持久化数据&#xff0c;PD提供TSO和Region的数据字典…

HackTheBox-Machines--Bashed

Bashed 测试过程 1 信息收集 NMAP 80 端口 目录扫描 http://10.129.155.171/dev/phpbash.min.php http://10.129.155.171/dev/phpbash.php 半交互式 shell 转向 交互式shell python -c import socket,subprocess,os;ssocket.socket(socket.AF_INET,socket.SOCK_STREAM);s.co…

优化CPU占用率及内存占用2

在标准化无线通信板时&#xff0c;关注过程序占用ram的问题&#xff0c;当时 发现每一个线程都会分配8M栈空间&#xff0c;这次换rk3568后&#xff0c;偶尔看了下RAM占用&#xff0c;吓了一跳&#xff0c;不但每个线程有8M栈空间&#xff0c;几乎每个线程都占用了64MB的一个RAM…

AOP进阶

黑马程序员JavaWeb开发教程 文章目录 一、通知类型1.1 通知类型1.2 注意事项1.3 PointCut 二、通知顺序2.1 执行顺序 三、切入点表达式3.1 切入点表达式3.2 切入点表达式-execution3.2 切入点表达式- annotation 四、连接点4.1 连接点 一、通知类型 1.1 通知类型 Around&…

部署专属网页版ChatGPT-Next-Web

背景 工作学习中经常使用chat-gpt, 需求是多端使用gpt问答&#xff0c;因此搭建一个网页版本方便多个平台使用。最后选择了 ChatGPT-Next-Web 部署说明 一键部署自己的web页面&#xff0c;因为是使用免费的vercel托管的&#xff0c;vercel节点在全球都有&#xff0c;理论上突…

oracle 12c DB卸载流程

1.运行卸载程序 [rootprimary1 ~]# su - oracle [oracleprimary1 ~]$ cd $ORACLE_HOME/deinstall [oracleprimary1 deinstall]$ ./deinstall Checking for required files and bootstrapping ... Please wait ... 这里选择3 、回车、y、y、回车、ASM 这里输入y 2.删除相关目录…

Midjourney应用:电商模特换装

今天我们应用的是Midjourney应用&#xff1a;电商模特换装 网上找到一件衣服&#xff0c;没有模特 方法一&#xff1a;两图片融合&#xff0c;BLEND命令&#xff0c;效果不是很理想失真 方法二&#xff1a;服装图片垫图说明细节缺失https://cdn.discordapp.com/attachments/1…

Iphone自动化指令每隔固定天数打开闹钟关闭闹钟(一)

注意&#xff1a;因为是第一次用iphone的快捷指令&#xff0c;不是很明白&#xff0c;所以之后多次运行发现有bug&#xff0c;所以快捷指令部分在下一章重新写&#xff0c;我用两个日期测试了&#xff0c;没问题&#xff0c;这一章可以当做熟悉快捷指令的一些操作用&#xff0c…

STM32高级控制定时器之输入捕获模式

目录 概述 1 输入捕获模式 1.1 原理介绍 1.2 实现步骤 1.3 发生输入捕获流程 2 使用STM32Cube配置工程 2.1 软件环境 2.2 配置参数 2.3 生成项目文件 3 功能实现 3.1 PWM调制占空比函数 3.2 应用函数库 4 测试 4.1 功能框图 4.2 运行结果 源代码下载地址&#xf…

【Word】调整列表符号与后续文本的间距

1. 默认的列表格式&#xff1a; 2. 修改间距&#xff1a; ************************************************** 分割线 ************************************************************ 3. 效果

推荐一款开源电子签章/电子合同系统

文章目录 前言一、项目介绍二、项目地址三、技术架构四、代码结构介绍五、功能模块六、功能界面首页面手写签名面板电子印章制作数字证书生成 总结 前言 大家好&#xff01;我是智航云科技&#xff0c;今天为大家分享一个免费开源的电子签字系统。 一、项目介绍 开放签电子签…

热门新游 2024 植物大战僵尸杂交版 Mac 版本下载安装详细教程

最近植物大战僵尸杂交版可谓是非常的火&#xff0c;好多主播都在播这款游戏&#xff0c;我一个 Mac 党也想玩&#xff0c;可奈何该游戏目前只有 PC 版本&#xff0c;经过一番折腾终于在我的 Mac 上安装上了该游戏&#xff0c;分享给大家 其实安装过程也很简单&#xff0c;只需…

AI视频下载:ChatGPT数据科学与机器学习课程

ChatGPT是一个基于OpenAI开发的GPT-3.5架构的AI对话代理。作为一种语言模型,ChatGPT能够理解并对各种主题生成类似人类的响应,使其成为聊天机器人开发、客户服务和内容创作的多用途工具。 此外,ChatGPT被设计为高度可扩展和可定制的,允许开发人员对其响应进行微调并将其集成到…

数组的应用-24点游戏

目录 24点游戏 游戏规则 游戏主要分为三部分 电脑出牌 用户输入算式 电脑判断胜负 总结 24点游戏 游戏规则&#xff1a; 54张扑克抽出大小王&#xff0c;剩余52张用来用于游戏&#xff1b;每一轮从52张牌中随机抽出4张&#xff1b;玩家运用加&#xff0c;减&#xff0…

JUC常见类

White graces&#xff1a;个人主页 &#x1f649;专栏推荐:Java入门知识&#x1f649; &#x1f649; 内容推荐:Java锁的策略&#x1f649; &#x1f439;今日诗词:苟利国家生死以,岂因祸福避趋之&#x1f439; ⛳️点赞 ☀️收藏⭐️关注&#x1f4ac;卑微小博主&#x1f64…

Windows系统WDS+MDT网络启动自动化安装

Windows系统WDS+MDT网络启动自动化安装 适用于在Windows系统上WDS+MDT网络启动自动化安装 1. 安装准备 1.下载windows server 2019、windows 10 pro的ISO文件,并安装好windows server 2019 2.下载windows 10 2004版ADK及镜像包 1.1 安装平台 Windows 111.2. 软件信息 软件…

模型优化——模型剪枝、模型量化、知识蒸馏

1.模型剪枝 1.1什么是模型剪枝&#xff1f; 深度学习网络模型从卷积层到全连接层存在着大量冗余的参数&#xff0c;大量神经元激活值趋近于0&#xff0c;将这些神经元去除后可以表现出同样的模型表达能力&#xff0c;这种情况被称为过参数化&#xff0c;而对应的技术则被称为模…

摸鱼大数据——select查询7-10

7、union联合查询 union: 对重复数据会去重 union all: 对重复数据不会去重 ​ 注意&#xff1a;union和union all中两边的字段&#xff08;类型、顺序&#xff09;要对应上 示例: use day08; select * from students; ​ select id,name from students where id in (95001,9…