算法分析神器—时间复杂度

一次讲清:时间复杂度到底怎么算(递归、二分、堆、贪心) 本文系统讲解四种高频算法的时间复杂度计算方法。递归算法需计算递归次数与每次操作,结合主定理分析;二分算法固定为O(logn),关键在于问题规模缩半;堆操作的时间复杂度由堆的调整过程决定;贪心算法复杂度取决于排序与遍历步骤。文章通过实例分析常见场景,并指出易错点,如递归中忽略合并操作、误判二分次数等,帮助读者掌握时间复杂度分析的核心逻辑。 阅读详情

时间复杂度是学习算法的基石,今天我们来聊聊为什么要引入时间复杂度,什么是时间复杂度以及如何去算一个算法的时间复杂度

刻画算法的运行时间

某日,克(就是著名的算法大师Knuth了0?wx_fmt=gif)叫来了慧子,打算给他补习一下基础知识,只见克写了一段非常简单的代码

0?wx_fmt=png

0?wx_fmt=jpeg

克

0?wx_fmt=png

你说一下这段代码会运行多长时间

这个...,得在计算机上跑一下才可以知道吧

0?wx_fmt=png

0?wx_fmt=jpeg

慧子

0?wx_fmt=jpeg

克

0?wx_fmt=png

恩恩,对的,那如果我改变n的大小为10000,你能够预测它的运行时间吗?

这个...,要不再测一次

0?wx_fmt=png

0?wx_fmt=jpeg

慧子

0?wx_fmt=jpeg

克面无表情

0?wx_fmt=jpeg

克

0?wx_fmt=png

我们要善于发现事物的内在规律

克看了一下慧子

这个程序的内在规律是什么呢?

0?wx_fmt=png

0?wx_fmt=jpeg

慧子

慧子看老师有点生气,开始虚心请教了

0?wx_fmt=jpeg

克

0?wx_fmt=png

你要预测当n=10000的时候,这个程序会运行多长时间,你首先要知道程序的运行时间都花在哪了?

0?wx_fmt=jpeg

0?wx_fmt=jpeg

克

0?wx_fmt=png

当电脑运行这段代码的时候,执行任何一条语句都需要花费时间,这是时间花费的主要地方

为了方便讨论,这里我们把每一条语句的执行时间都看做是一样的,记为一个时间单元

0?wx_fmt=jpeg

克

0?wx_fmt=png

你看一下刚才的程序都有哪些语句

0?wx_fmt=jpeg

0?wx_fmt=jpeg

克

0?wx_fmt=png

你看,这个程序有这么几个地方消耗了时间

①蓝色框的两条语句,花费两个时间单元 

 ②黑色框的一条语句,花费n+1个时间单元

③红色框的两条语句,花费2*n个时间单元

0?wx_fmt=jpeg

克

0?wx_fmt=png

那么一共花费了3n+3个时间单元,可以看出,程序消耗的时间和你的n成线性关系

这不是数学吗,慧子心里想到

0?wx_fmt=jpeg

克

0?wx_fmt=png

现在我用T(n)表示这个程序运行了多长时间,那么这个程序运行的时间就可以写成T(n)=3n+3

其中的n被我们称为输入的长度,其实就是你处理问题的大小

克顺手画了这个函数的图

0?wx_fmt=png

本文主要讨论问题规模和运行时间的关系,假定不同输入和运行时间基本无关

哦,我懂了,要预测程序的时间,我可以把运行时间函数求出来

0?wx_fmt=png

0?wx_fmt=jpeg

慧子

0?wx_fmt=jpeg

克

0?wx_fmt=png

恩恩,对的

这个函数表达式看起来挺复杂的

0?wx_fmt=png

0?wx_fmt=jpeg

慧子

0?wx_fmt=jpeg

克

0?wx_fmt=png

我们常常会对这个函数进行简化,使得它既简单又不失函数的主要特性

哦?怎么简化

0?wx_fmt=png

0?wx_fmt=jpeg

慧子

时间复杂度

0?wx_fmt=jpeg

克

0?wx_fmt=png

我们一般只关心随着问题规模n趋于无穷时函数中对函数结果影响最大的项,也就是最高次项

比如说:T(n)=3n+3,当n非常大的时候常数3和n的系数3对函数结果的影响就很小了    

0?wx_fmt=jpeg

0?wx_fmt=jpeg

克

0?wx_fmt=png

所以一般我们会保留最高次项并忽略该项的系数

比如:T(n)=n+1 忽略常数项 T(n) ~ n

T(n)=n+n^2 忽略低阶项 T(n) ~ n^2

T(n)=3n 忽略最高阶的系数 T(n) ~ n

这个忽略低阶项是什么意思

0?wx_fmt=png

0?wx_fmt=jpeg

慧子

0?wx_fmt=jpeg

克

0?wx_fmt=png

所谓低阶项,简单地说就是当n非常大时,这个项相对于另外一个项很小,可以忽略,比如n相对于n^2,n就是低阶项

哦,我怎么判断哪个是高阶,哪个是低阶呢?

0?wx_fmt=png

0?wx_fmt=jpeg

慧子

0?wx_fmt=jpeg

克

0?wx_fmt=png

具体要用数学知识,对你而言,你只需记住下面的大小关系就行了,到时按照这个进行忽略(相对较小的忽略)

0?wx_fmt=png

还好不用掌握那头疼的数学,慧子心中想到

简化完了之后呢?

0?wx_fmt=png

0?wx_fmt=jpeg

慧子

慧子把话题又拉了回来

0?wx_fmt=jpeg

克

0?wx_fmt=png

化简完后的函数可以近似地代表原来函数的总体趋势

0?wx_fmt=jpeg

0?wx_fmt=jpeg

克

0?wx_fmt=png

简化后的式子被称为这个程序算法的时间复杂度,记做O(f(n)),f(n)就是简化后的式子,比如说刚开始讨论的T(n)=3n+3,简化后T(n)~f(n)=n,那我们记为O(n)

更准确地说O代表了运行时间函数的一个渐进上界,即T(n)在数量级上小于等于f(n)

哦,原来时间复杂度可以表示某个算法的运行时间的趋势,大致地度量算法效率的好坏, 那我该如何算这个时间复杂度呢?

0?wx_fmt=png

0?wx_fmt=jpeg

慧子

时间复杂度的计算

0?wx_fmt=jpeg

克

0?wx_fmt=png

从前面可以总结出计算算法复杂度大O的方法

一、得出运行时间的函数                             

二、对函数进行简化                                    

①用常数1来取代运行时间中所有加法常数  

②修改后的函数中,只保留最高阶项           

③如果最高阶项存在且不是1,则忽略这个项的系数

0?wx_fmt=jpeg

克

0?wx_fmt=png

举个例子吧,先来看这样一段代码

0?wx_fmt=png

0?wx_fmt=jpeg

克

0?wx_fmt=png

显然,T(n)=3,对这个函数进行简化,用常数1取代常数3,然后取代后的函数没有最高阶项,那么这个算法的时间复杂度就是O(1).

O(1)也被称为常数阶

每次都要把时间函数算出来,好复杂,有没有简便一点的方法

0?wx_fmt=png

0?wx_fmt=jpeg

慧子

0?wx_fmt=jpeg

克

0?wx_fmt=png

这个还真可以耍耍小聪明,一般来说,最内层执行次数最多的语句就决定了整个算法的趋势

0?wx_fmt=png

0?wx_fmt=jpeg

克

0?wx_fmt=png

你只要看看最内层的语句执行次数的规律就行了,这个内层打印语句随着问题规模n的增加会呈线性增加,直接就可以判定复杂度为O(n)

这个方法真棒,那么按照这个方法就很容易得出下面这个嵌套的两层for循环的复杂度为O(n^2)了

0?wx_fmt=png

0?wx_fmt=jpeg

慧子

慧子随手写了一段嵌套循环的代码

0?wx_fmt=png

0?wx_fmt=jpeg

克

0?wx_fmt=png

恩恩,对的,最内层的语句随n的增加会呈二次函数的规律执行,代表了这个算法执行时间的一个趋势

我听说有一个很神奇的函数叫对数函数,它随着自变量的增大,因变量增长的很慢,这个应该很受欢迎吧

0?wx_fmt=png

0?wx_fmt=jpeg

慧子

0?wx_fmt=jpeg

克

0?wx_fmt=png

嗯嗯,对的,对数函数的趋势显然比线性函数好(对数函数随着自变量的增大因变量增长的很慢)

0?wx_fmt=png

接着,克又写了一段时间复杂度为对数的代码

0?wx_fmt=png

0?wx_fmt=jpeg

克

0?wx_fmt=png

你看,这段代码的复杂度就为对数级别的,O(logn)

这个怎么分析

0?wx_fmt=png

0?wx_fmt=jpeg

慧子

一向数学不太好的谦子此时有点懵

0?wx_fmt=jpeg

克

0?wx_fmt=png

和之前的分析方法一样,我们着重看执行次数最多的内层代码语句

0?wx_fmt=png

0?wx_fmt=jpeg

克

0?wx_fmt=png

每循环一次,sum就给自身乘以2,乘了多少次就跳出循环了呢(大于等于n)?不知道,就设为x吧,那么2^x=n,解出x=logn,这说明随着n的增大,最消耗时间的内层语句是呈指数变化的

哦,我懂了,原来如此

0?wx_fmt=png

0?wx_fmt=jpeg

慧子

0?wx_fmt=jpeg

克

0?wx_fmt=png

复杂度的内容很多,你只要理解它的含义以及会分析简单的算法就行了,以后遇到复杂的,为师会给你传授的

好的

0?wx_fmt=png

0?wx_fmt=jpeg

慧子

慧子与老师道了别

本文转自微信公众号“趣谈编程”

0?wx_fmt=jpeg

0?wx_fmt=png

你看到的只是冰山一角, 更多精彩文章,请移步《2016文章精华》或者《2017文章精华》


码农翻身

用故事讲述技术

0.jpeg

<算法>回顾所学的概念,总结基础知识和经典算法概念 🎉前言 终是到了标志着大二结束的期末考试了,对于《算法设计与分析》这门课,我需要总结一下学过的所有算法的思想以及老师补充的关于两个复杂度和递归的概念思想,以及更深层次的理解,比如用画图的方式表达出来,我觉得可以用博客记录总结一下,分享给大家,希望能有所帮助。 算法分析的本质 算法分析就是对时间复杂性和空间复杂性进行分析 时间复杂度 概念 时间复杂性又叫时间复杂度,是对算法运行时间长短的度量。 人们通常只考虑三种情况下的时间复杂性:最坏、最好、平均情况。 计算方法 第一步:声明哪些代码是基...... 阅读详情

相关推荐

XPe开发初体验(一)XPe概述

XP Embedded是微软Windows Embedded产品线中非常重要的一环,不过比起大名鼎鼎的Windows Embedded CE,XPe显得过于低调了。在接下来的一段时间里,我希望能够用六篇的篇幅来描述一下XPe的整个开发过程。这个系列文章主要是针对有Windows编程经验,但是没有嵌入式开发经验的开发者,提供一些概念和开发过程的初步介绍。XP Embedded是一个基于Windo

aawolf = new Mobile.MVP 1万+

计算算法复杂度FLOPs

搜遍全网,流传的在网上的能方便计算FLOPs的有3个小工具。 THOP: PyTorch-OpCounter torchstat ptflops 一个不行的话多试两个。我的程序用2、3报错,最终用的1

qq_44901346的博客 839

计算机组成原理实验二 运算器组成实验

事实上,ALU的设计是在全加器的基础上,对全加器功能的扩展来实现符合要求的多种算术/逻辑运算的功能。为了实现多种功能的运算,An、Bn数据是不能直接与全加器相连接的,它们受到功能变量F3—F1的制约,因此,可由An、Bn数据和功能变量F3-F1组合成新的函数Xn 、Yn,然后,再将Xn 、Yn和下一位进位Cn-1通过全加器进行全加运算以实现所需的运算功能。AC寄存器可用来存储ALU的输入以实现两个操作数的运算操作,也可以用来存储来自ALU的结果,以将这些结果反馈给ALU以进行更多的处理。

qq_63574533的博客 1450

算法复杂度评估

在评估一个算法时,测量算法的复杂性是第一步。在特定处理器上运行算法所要求的时钟决定了处理能力,它取决于架构,不同的处理器架构其处理能力是有变化的。而算法的存储器需求明显不会改变。绝大多数的DSP算法对一组样值进行处理,这样的一组样值称为一个帧。一组样值组成一个帧将不可避免引入延迟,并产生处理延迟。国际电联(ITU)规定了每种算法的可接受延迟标准。 1. 时间分析法 通过在算法的参考代码(C/C++/C#或M代码)加入时间统计函数。来实现对算法在整个系统中所占时间作以统计。 优点:实现简单直观的得到...

audio_algorithm的博客 1733

永磁同步电机无传感器控制:HFI与ESMO技术详解

高频注入(HFI)和增强型滑模观测器(ESMO)是现代永磁同步电机(PMSM)无传感器控制的核心技术。HFI通过注入高频信号利用电机凸极效应获取转子位置,而ESMO则通过改进传统滑模观测器,有效抑制抖振并提升动态响应。这两种技术的结合特别适用于零低速区域的位置估计,在工业伺服、电动汽车等领域有广泛应用。方波高频注入作为实现方案之一,具有计算量小、实现简单的特点,配合自适应滤波等信号处理技术,可以在保证精度的同时降低系统成本。

weixin_29183637的博客 355

Isaacgym使用操作指南

Isaac Gym 是一个强大的仿真工具,特别适合那些需要进行大规模并行仿真和训练的机器人和强化学习任务。通过 GPU 加速、深度学习集成和丰富的物理仿真能力,Isaac Gym 能够显著提高仿真和训练效率,是机器人学和 AI 研究中的一大利器。

Tony Wey的博客 1万+

时间复杂度计算方法

在学习数据结构阶段,认识的第一个概念应该就是时间复杂度了。时间复杂度是一个数学上的一个函数式,该函数式计算的基本执行次数,就是时间复杂度。通俗的说,时间复杂度就是衡量这个算法的运行时间长短,效率高低的一个手段,它是通过粗略的计算算法的执行次数来衡量的。那时间复杂度该怎么计算呢?

m0_68190153的博客 1303

相机标定原理与张氏标定法

这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 欢迎使用Markdown编辑器 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Mar

heeweii的博客 2280

【亲测免费】 Lizard:多功能代码复杂度分析工具

Lizard 是一款强大的开源代码复杂度分析工具,支持多种编程语言,包括 C/C++、Java、C#、JavaScript、TypeScript、Objective-C、Swift、Python、Ruby、TTCN-3、PHP、Scala、GDScript、Golang、Lua、Rust、Fortran、Kotlin、Solidity 和 Erlang 等。Lizard 不仅能够计算代码的圈复杂度...

gitblog_01045的博客 1764

【GlobalMapper精品教程】006:Excel表格(.xls)或文本(.txt .csv)坐标文件生成矢量点

原始的坐标数据如下图所示,其中坐标为Lat经度,LNG纬度,均为十进制度的形式,一般软件都支持十进制度的格式,如果不支持,你可以尝试使用度分秒的形式,图中的DDMMSS-LAT为纬度,DDMMSS-LNG为经度。打开globalmapper软件,点击【打开数据文件】,选择坐标数据文件(案例中的数据位配套实验数据包中的data006.rar)气象台站分布点坐标.xls。选择坐标系:本案例数据采用的是经纬度,因此选择Geographic(Latitude/Longitude),基准选择WGS84,点击确定。

智慧空间实验室 2570

036、算子映射:如何将ONNX算子映射到NPU硬件指令?

《算子映射:ONNX到NPU的转换艺术》 本文深入探讨了将ONNX算子映射到NPU硬件指令的技术挑战与实践经验。作者通过真实案例揭示了映射过程中的常见陷阱,如Reshape算子被错误映射导致分类错误。文章详细分析了三种映射策略(直接映射、拆分映射和融合映射),并强调映射表在编译器中的核心作用。特别针对动态形状、精度对齐等难题提供了解决方案,分享了编写映射表时的实用铁律,包括先优化后映射、严格单元测试等。最后指出,成功的算子映射需要在数学语义、硬件约束和性能优化之间找到精确平衡,这种看似枯燥的工作实则决定着N

m0_50546716的博客 186

算法分析神器——时间复杂度

这是之前看到的一篇很直观易懂的文章,放于此: 添加链接描述

weixin_45459911的博客 261

MATLAB 基于深度学习的步态识别算法仿真

步态识别是一种通过分析人体行走方式来识别身份的技术。基于深度学习的步态识别算法利用卷积神经网络 (CNN) 提取步态特征,并通过分类器进行身份识别。基于深度学习的步态识别算法是实现身份识别的重要手段,具有广泛的应用前景。MATLAB 提供了丰富的工具和函数,可以方便地进行算法仿真和性能评估。

走向CTO的路上... 518

有机婴幼儿食品品牌Once Upon a Farm的成功案例分析

有机婴幼儿食品市场近年来快速增长,其中冷藏技术和有机认证成为行业热点。HPP高压灭菌技术作为核心工艺,能在低温条件下有效保留食材营养,相比传统热加工方式,维生素保留率提升至90%以上。这种技术特别适合婴幼儿食品领域,因为该人群对营养完整性和食品安全性要求极高。Once Upon a Farm通过结合HPP技术和冷链供应链,成功打造了差异化产品线,其冷藏有机婴幼儿辅食填补了市场空白。品牌还创新性地采用可挤压式立袋包装,提升使用便利性。从商业角度看,这种技术组合创造了50-60%的定价溢价空间,为食品创业者提供

weixin_33898876的博客 290

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

谈谈入门都要学的知识:算法分析神器----时间复杂度

1.时间复杂度的剖析 1.1 概念 我们先来看一下官方的定义如下: 若存在函数 f(n),使得当n趋近于无穷大时,T(n)/ f(n)的极限值为不等于零的常数,则称 f(n)是T(n)的同数量级函数。 记作 T(n)= O(f(n)),称O(f(n)) 为算法的渐进时间复杂度,简称时间复杂度。 渐进时间复杂度用大写O来表示,所以也被称为大O表示法。 是不是刚看起来的时候特别别扭,没错的,我...

qq_38834531的博客 255

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

算法分析之【时间复杂度】

时间复杂度 当电脑运行下面这段代码的时候,执行任何一条语句都需要花费时间(为了方便讨论,这里我们把每一条语句的执行时间都看做是一样的,记为一个时间单元) 这个程序有这么几个地方消耗了时间: ① 蓝色框的两条语句,花费2个时间单元 ② 黑色框的一条语句,花费n+1个时间单元 ③ 红色框的两条语句,花费2*n个时间单元 那么一共花费了3n+3个时间单元,可以看出,程序消耗的时间和n成线性关系 ...

Henry_626的博客 1012

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

时间复杂度

摘抄自: 算法分析神器—时间复杂度 一套图 搞懂“时间复杂度” 目录 一、代码消耗的的时间单位分析 二、什么是时间复杂度? 三、计算时间复杂度? 一、得出运行时间的函数 二、对函数进行简化 四、时间复杂度排行 五、不同时间复杂度举例 1、O(1)...

码放南山 332

chatgpt赋能python:Python阶乘怎么写

首先,让我们来了解一下什么是阶乘。阶乘通常表示成一个正整数n的乘积,例如,n的阶乘(记作n!)表示n×(n-1)×(n-2)×…×3×2×1。特别的,0!的值为1,1!的值也为1。阶乘在数学上具有广泛的应用,尤其是在组合数学和概率论中。本文由chatgpt生成,文章没有在chatgpt生成的基础上进行任何的修改。以上只是chatgpt能力的冰山一角。作为通用的Aigc大模型,只是展现它原本的实力。对于颠覆工作方式的ChatGPT,应该选择拥抱而不是抗拒,未来属于“会用”AI的人。

reilust的博客 239

chatgpt赋能python:Python寻找平方数:介绍与算法分析

平方数是指一个数能够表示为某个整数的平方,例如1、4、9、16、25等等。平方数具有很好的数学性质,在许多科学领域中有着广泛的应用。本文由chatgpt生成,文章没有在chatgpt生成的基础上进行任何的修改。以上只是chatgpt能力的冰山一角。作为通用的Aigc大模型,只是展现它原本的实力。对于颠覆工作方式的ChatGPT,应该选择拥抱而不是抗拒,未来属于“会用”AI的人。🧡AI职场汇报智能办公文案写作效率提升教程 🧡专注于AI+职场+办公方向。下图是课程的整体大纲下图是。

boRRjxBZRf的博客 393

【学习挑战赛】经典算法之直接选择排序

书接上文,今天带来直接选择排序算法的解析过程,从概念到实现一步一个脚印的完成。天气那么热,快来点简单算法解解渴! 这篇文章的最后我也是总结了一般计算时间复杂度的方法,大家可以根据本篇博文去分析时间复杂度或者再以后的做题中思考、锻炼。...............

叶落秋白的博客 1908

广度优先搜索解决欧拉回路时间复杂度_洛谷试炼场------题目

新手村任何一个伟大的目标,都有一个微不足道的开始。洛谷的第一个任务勇敢的迈出第一步,了解下语言和洛谷。跟着书本和老师走,不会难的。顺序与分支计算机的智能性开始得以体现,因为计算机能够根据不同的条件选择了。循环!循环!循环!计算机最不怕的就是重复。你让它做10000次同样的事它也不怕啦,但是让他做1亿亿次的话……数组跟数组有关的题目基本上都要用到循环,所以请先完成1-3。简单字符串计算机不仅可以处理...

weixin_34474759的博客 248
上一篇: 当多线程并发遇到Actor
下一篇: 函数式编程圣经
码农翻身
码农翻身 《码农翻身》作者 《码农翻身》作者
博客等级 码龄8年 3万+粉丝 1084原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值