网站首页 > 技术文章 正文
时间复杂度
前言
我们在程序开发过程中为了衡量一个算法的好坏制定了两个标准时间复杂度和空间复杂度,因为程序运行的时间长短和占用内存的大小直接影响到程序的执行效率。
但我们需要注意程序运行的时间长短不仅仅取决于代码,还有运行环境、硬件、数据量等因素影响,什么意思呢?
- 硬件:当一段相同的代码同时在2C4G和4C8G上的机器运行因为机器计算力不一样,所以程序运行时间大概率不同(特别是代码计算量大时)。
- 运行时环境:当一台机器上大部分资源被其它服务所占用,另外一台机器上面没有其它服务,那么一段相同的代码在两个硬件相同机器上执行时间长短会不一样。
- 数据量:一段相同的代码定义入参为n(或输入规模),代码片段会循环n次,那么n=1和n=1w执行时间长度上肯定不一样。
所以说时间复杂度并不能直接等于代码运行的时间长短,这里的时间复杂度指的是代码基本操作执行的次数。
基本操作执行次数
所有案例只考虑主要流程的执行次数
案例一
如存在一个面包长10cm,每2分钟只能吃1cm,那么吃完这个面包需要多长时间呢?
很明显答案为10*2=20分钟,所以当吃面包的速度不变的情况下面包长n cm那么就需要花费2n的时间才能吃完面包,这里可以记作T(n) = 2n。
public void method1(int n){
for (int i = 0; i < n; i++) {
System.out.println("吃一口面包");
System.out.println("吃完了~");
}
}
案例二
假设再存在一个面包长16cm,每过5分钟吃掉该面包的一半,那么面包变为1cm需要花费多长时间?
这个计算稍微复杂点,第五分钟吃掉8cm、第十分钟吃掉4cm、第十五分钟吃掉2cm、第二十分钟吃掉第1cm,还剩1cm,就是将面包长度不断的做等分,这就是数学中的对数,这里答案就是5 * log2(16) = 20,当面包长度为n时这里可以记作T(n) = 5logn。
public void method2(int n){
for (int i = n; i > 1; i=i/2) {
System.out.println("吃一口面包");
System.out.println("吃一口面包中2");
System.out.println("吃一口面包中3");
System.out.println("吃一口面包中4");
System.out.println("吃完了~");
}
}
案例三
假设存在一个面包长10cm,吃掉第一个1cm需要1分钟,吃掉第二个1cm需要2分钟,吃掉第三个1cm需要3分钟,那么一个面包吃完需要多少分钟呢?
这其实就是1到10的累加,所以当面包长度为n时需要的时间就可以记作T(n) = (n / 2) * (1+n) ,变化为T(n) = 0.5n + 0.5n^2^。
public void method3(int n){
for (int i = 0; i < n; i++) {
for (int j = 0; j <i ; j++) {
System.out.println("吃一口面包中"+(j+1));
}
System.out.println("吃完了~");
}
}
案例四
假设存在一个鸡腿,吃一个鸡腿需要两分钟那么吃完整个鸡腿需要多长时间。
这个答案就太简单了两分钟,需要的时间简单记为T(n) = 2。
渐进时间复杂度
到这里我们知道了程序基本操作执行的次数,那是不是就直接等于时间复杂度了呢?显然也不是,我们看到除案例四外其余三个都是受输入数字n的影响,所以这里需要引进渐进时间复杂度,也称为大O表示法,来简化时间复杂度的表示,大O表示法有如下原则
- 如果运行时间也就是T(n)是常数量级,那么用数字1表示。
- 只保留时间函数中的最高阶项。
- 如果最高阶项存在,那么省略最高阶项前面的系数。
根据这个原则就可以得出前面案例的时间复杂度
- 案例一:运行时间表示为T(n) = 2n,按照原则3省略最高阶项前面的系数,时间复杂度为O(n)。
- 案例二:运行时间表示为T(n) = 5logn,按照原则3省略最高阶项前面的系数,时间复杂度为O(logn)。
- 案例三:运行时间表示为T(n) = 0.5n + 0.5n^2^,按照原则2和原则3只取最高阶项和省略最高阶项前面的系数,时间复杂度为O(n^2^)。
- 案例四:运行时间表示为T(n) = 2,按照原则1所有常数用数字1表示,时间复杂度为O(1)。
不难看出这些时间复杂度有如下排序
**O(1) < O(logn) < O(n) < O(n^2^) **
猜你喜欢
- 2024-11-10 选择排序代码及时间空间复杂度 简单选择排序时间复杂度分析
- 2024-11-10 排序算法汇总 排序算法 简书
- 2024-11-10 「时间管理」JavaScript算法时间、空间复杂度分析
- 2024-11-10 数据结构与算法——常见排序算法分享
- 2024-11-10 数据结构与算法-排序(八)计数排序(Counting Sort)
- 2024-11-10 快速排序算法 快速排序算法的平均时间复杂度为
- 2024-11-10 上个厕所的功夫,就学会了“快速排序”算法
- 2024-11-10 常用排序方法使用场景和性能对比分析
- 2024-11-10 数据结构:复杂度分析(时间复杂度和空间复杂度)
- 2024-11-10 堆排序代码及时间空间复杂度 堆排序的算法及代码实现
你 发表评论:
欢迎- 11-13第一次养猫的人养什么品种比较合适?
- 11-13大学新生活不适应?送你舒心指南! 大学新生的不适应主要有哪些方面
- 11-13第一次倒班可能会让人感到有些不适应,以下是一些建议
- 11-13货物大小不同装柜算法有哪些?怎么算?区别有哪些?
- 11-13五大基本算法 五大基本算法是什么
- 11-13高级程序员必备:分治算法分享 分冶算法
- 11-13最快速的寻路算法 Jump Point Search
- 11-13手机实时人工智能之「三维动作识别」:每帧只需9ms
- 最近发表
- 标签列表
-
- oraclesql优化 (66)
- 类的加载机制 (75)
- feignclient (62)
- 一致性hash算法 (71)
- dockfile (66)
- 锁机制 (57)
- javaresponse (60)
- 查看hive版本 (59)
- phpworkerman (57)
- spark算子 (58)
- vue双向绑定的原理 (68)
- springbootget请求 (58)
- docker网络三种模式 (67)
- spring控制反转 (71)
- data:image/jpeg (69)
- base64 (69)
- java分页 (64)
- kibanadocker (60)
- qabstracttablemodel (62)
- java生成pdf文件 (69)
- deletelater (62)
- com.aspose.words (58)
- android.mk (62)
- qopengl (73)
- epoch_millis (61)
本文暂时没有评论,来添加一个吧(●'◡'●)