时间复杂度的表示、分析、计算方法……一文带你看懂时间复杂度!

2024-05-14 21:18

本文主要是介绍时间复杂度的表示、分析、计算方法……一文带你看懂时间复杂度!,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

如果你还在发愁究竟怎么计算时间复杂度和空间复杂度,那你是来对地方了!

名词解释:

在计算机科学中,时间复杂性,又称时间复杂度,算法的时间复杂度是一个函数,它定性描述该算法的运行时间。这是一个代表算法输入值的字符串的长度的函数。时间复杂度常用大O符号表述,不包括这个函数的低阶项和首项系数。使用这种方式时,时间复杂度可被称为是渐近的,亦即考察输入值大小趋近无穷时的情况。

时间复杂度的表示方法

其实就是算法(代码)的执行效率,算法代码的执行时间。我们来看下面一个简单的代码:

int sumFunc(int n) {  int num = 0;     // 执行一次  for (int i = 1; i <= n; ++i) {  // 执行n次    num = num + i;         // 执行n次  }        return num;}

假设,每行代码的执行时间为t,那么这块代码的时间就是(2n+2)*t

由此得出:代码执行时间T(n)与代码的执行次数是成正比的!

那么我们来看下一个例子:

int sumFunc(int n) {  int num = 0;    // 执行一次  for (int i = 1; i <= n; ++i) {       // 执行n次    for (int j = 1; j <= n; ++j) {     //执行n*n次      num = num + i * j;         // 执行n*n次    }  }}

同理,该代码执行时间为(2n*n+n+1)*t,没意见吧?继续往后看!

注意:在数据结构/算法中,通常使用T(n)表示代码执行时间,n表示数据规模大小,f(n)表示代码执行次数综合,所以上面这个例子可以表示为f(n)=(2n*n+n+1)*t,其实就是一个求总和的式子,O(大写O)表示代码执行时间与 f(n) 成正比例。

根据上面两个例子得出结论:代码的执行时间 T(n)与每行代码的执行次数 n 成正比,人们把这个规律总结成这么一个公式: T(n) = O(f(n))

所以呢,第一个例子中的 T(n)=O(2n+1),第二个例子中的 T(n)=O(2n*n+n+1),这就是时间复杂度表示法,也叫大O时间复杂度表示法。

但是,大O时间复杂度并不具体表示代码真正的执行时间,而是表示代码执行时间随数据规模增长的变化趋势,所以,也叫作渐进时间复杂度,简称时间复杂度

与泰勒公式相反的是,算了,扯哪去了…

当n变得越来越大时,公式中的低阶,常量,系数三部分影响不了其增长趋势,所以可以直接忽略他们,只记录一个最大的量级就可以了,所以上述两个例子实际他们的时间复杂度应该记为:T(n)=O(n) ,T(n)=O(n*n)

我想你应该明白大致是怎么回事了,那么我们来看看如何去计算它?

时间复杂度的分析与计算方法

(1)循环次数最多原则

我们上面说过了,当n变得越来越大时,公式中的低阶,常量,系数三部分影响不了其增长趋势,可以直接忽略他们,只记录一个最大的量级就可以了。因此我们在计算时间复杂度时,只需关注循环次数最多的那段代码即可。

int sumFunc(int n) {int sum = 0;     //执行1次,忽略不计for (int i = 0; i < n; i++) {sum += i;    // 循环内执行次数最多,执行次数为n次,因此时间复杂度记为O(n)}  return sum;    //执行1次,忽略不计
}
 

 

(2)加法原则

int sumFunc(int n) {int sum = 0;     //常量级,忽略for (int i = 0; i < 99; i++) {sum += i;  //执行100次,还是常量级,忽略}for (int i = 0; i < n; i++) {sum += i;  //执行n次}for (int i = 0; i < n; i++){for (int j = 0; j < n; j++) {sum += i;  //执行n*n次}}return sum;
}

上述例子中,最大的两块代码时间复杂度分别为 O(n)和O(n*n),其结果本应该是:T(n)=O(n)+O(n*n),我们取其中最大的量级,因此整段代码的复杂度为:O(n * n)

所以得出结论:量级最大的那段代码时间复杂度=总的时间复杂度

(3)乘法原则

嵌套代码的复杂度等于嵌套内外代码复杂度的乘积

void Func1(int n) {for (int i = 0; i < n; i++) {Func2(n);  //执行n次,每次都会调用Func2函数执行n次}
}
void Func2(int n) {int sum = 0;for (int i = 0; i < n; i++){sum += 1;  //执行n次}
}

因此这段代码时间复杂度为O(n) * O(n) = O(n*n) = O(n*n)

同理,如果将其中一个n换成m,那么它的时间复杂度就是O(n*m)

常见的几种时间复杂度

 

(1)O(1)常量级时间复杂度

void Func(void) {for (int i = 0; i < 100; i++) {printf("hello");  //执行一百次,也是常量级,记为O(1)}
}
void Func(void) {printf("hello");printf("hello");  printf("hello");//各执行一次,还是记为O(1)
}

相信你也看明白了,O(1)不是说代码只有一行,这个1它代表的是一个常量,即使它有以前一万行这样的也是O(1),因为它是固定的不会变化(也就是常量),所以凡是常量级复杂度代码,均记为O(1)

(2)常见的O(n)复杂度

void Func(int n) {for (int i = 0; i < n; i++) {printf("hello");}
}

不用多说了吧!继续!

(3)O(logn),O(nlogn) ,这就有点难度了!

首先我们来回忆以下换底公式:

记住公式啊,来看例子:

void Func(int n) {for (int i = 1; i < n; i++) {i = i * 2;}
}
可以看出,i = i * 2这行代码执行次数是最多的,那么到底执行了多少次呢?

第一次 i=2,执行第二次 i=4,执行第三次 i=8…

假设它执行了x次,那么x的取值为:

当上述代码的2改成3的时候,x的取值也就是:

当然不管log的底数是几,是e也好,是10也罢,统统记为:

这是为啥子念?由换底公式可以计算出:

换底之后,可以看出log3(2)其实就是一个常数,忽略它!而在这场游戏中,log默认就是以2为底的,所以统统记为O(logn)。

void Func(int n) {for (int i = 0; i < n; i++) {Func2(n);    //执行n次,嵌套调用,每次调用执行logn次}
}
void Func2(int n) {for (int i = 0; i < n; i++){i = i * 2;    //执行logn次}
}
所以这个O(nlogn)也很好理解了吧!

其他就不赘述了,相信聪明的你一定可以举一反三!如果对你有帮助,就点个“在看”支持下作者吧!

这篇关于时间复杂度的表示、分析、计算方法……一文带你看懂时间复杂度!的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/989874

相关文章

问题:第一次世界大战的起止时间是 #其他#学习方法#微信

问题:第一次世界大战的起止时间是 A.1913 ~1918 年 B.1913 ~1918 年 C.1914 ~1918 年 D.1914 ~1919 年 参考答案如图所示

[职场] 公务员的利弊分析 #知识分享#经验分享#其他

公务员的利弊分析     公务员作为一种稳定的职业选择,一直备受人们的关注。然而,就像任何其他职业一样,公务员职位也有其利与弊。本文将对公务员的利弊进行分析,帮助读者更好地了解这一职业的特点。 利: 1. 稳定的职业:公务员职位通常具有较高的稳定性,一旦进入公务员队伍,往往可以享受到稳定的工作环境和薪资待遇。这对于那些追求稳定的人来说,是一个很大的优势。 2. 薪资福利优厚:公务员的薪资和

时序预测 | MATLAB实现LSTM时间序列未来多步预测-递归预测

时序预测 | MATLAB实现LSTM时间序列未来多步预测-递归预测 目录 时序预测 | MATLAB实现LSTM时间序列未来多步预测-递归预测基本介绍程序设计参考资料 基本介绍 MATLAB实现LSTM时间序列未来多步预测-递归预测。LSTM是一种含有LSTM区块(blocks)或其他的一种类神经网络,文献或其他资料中LSTM区块可能被描述成智能网络单元,因为

java中查看函数运行时间和cpu运行时间

android开发调查性能问题中有一个现象,函数的运行时间远低于cpu执行时间,因为函数运行期间线程可能包含等待操作。native层可以查看实际的cpu执行时间和函数执行时间。在java中如何实现? 借助AI得到了答案 import java.lang.management.ManagementFactory;import java.lang.management.Threa

时间服务器中,适用于国内的 NTP 服务器地址,可用于时间同步或 Android 加速 GPS 定位

NTP 是什么?   NTP 是网络时间协议(Network Time Protocol),它用来同步网络设备【如计算机、手机】的时间的协议。 NTP 实现什么目的?   目的很简单,就是为了提供准确时间。因为我们的手表、设备等,经常会时间跑着跑着就有误差,或快或慢的少几秒,时间长了甚至误差过分钟。 NTP 服务器列表 最常见、熟知的就是 www.pool.ntp.org/zo

20170723 做的事 ecdsa的签名验证时间短于bls signature

1 今天在虚拟机 /home/smile/Desktop/20170610/Test//time_ecdsa 文件夹下,找到ecdsa的验证时间是 989.060606μs μs 先 make ,然后run。 再取BLS的签名生成时间: ./run  2  gnuplot 画图,画对比的时间 gnuplot 画图参考教程 http://blog.sciencen

高度内卷下,企业如何通过VOC(客户之声)做好竞争分析?

VOC,即客户之声,是一种通过收集和分析客户反馈、需求和期望,来洞察市场趋势和竞争对手动态的方法。在高度内卷的市场环境下,VOC不仅能够帮助企业了解客户的真实需求,还能为企业提供宝贵的竞争情报,助力企业在竞争中占据有利地位。 那么,企业该如何通过VOC(客户之声)做好竞争分析呢?深圳天行健企业管理咨询公司解析如下: 首先,要建立完善的VOC收集机制。这包括通过线上渠道(如社交媒体、官网留言

Python几种建表方法运行时间的比较

建立一个表[0,1,2,3.......10n],下面几种方法都能实现,但是运行时间却截然不同哦 import time#方法一def test1(n):list=[]for i in range(n*10):list=list+[i]return list#方法二def test2(n):list=[]for i in range(n*10):list.append(i)#方法三d

打包体积分析和优化

webpack分析工具:webpack-bundle-analyzer 1. 通过<script src="./vue.js"></script>方式引入vue、vuex、vue-router等包(CDN) // webpack.config.jsif(process.env.NODE_ENV==='production') {module.exports = {devtool: 'none

【Qt6.3 基础教程 16】 掌握Qt中的时间和日期:QTimer和QDateTime的高效应用

文章目录 前言QTimer:定时任务的强大工具QTimer的基本用法高级特性:单次定时器 QDateTime:处理日期和时间获取当前日期和时间日期和时间的格式化输出日期和时间计算 用例:创建一个倒计时应用结论 前言 在开发桌面应用程序时,处理时间和日期是一个常见且重要的任务。Qt框架提供了强大的工具来处理与时间相关的功能,其中QTimer和QDateTime是最核心的类。本