当前位置: 首页 > news >正文

从【时间复杂度】到【函数的渐进上界】

函数渐进上界:一般意义上的时间复杂度

给定一个输入大小为 n 的函数:

void algorithm(int n) {int a = 1;  // +1a = a + 1;  // +1a = a * 2;  // +1// 循环 n 次for (int i = 0; i < n; i++) { // +1(每轮都执行 i ++)System.out.println(0);    // +1}
}

设算法的操作数量是一个关于输入数据大小 n 的函数,记为 T(n),则以上函数的操作数量为:

T(n) = 3+2n

T(n) 是一次函数,说明其运行时间的增长趋势是线性的,因此它的时间复杂度是线性阶。

我们将线性阶的时间复杂度记为O(n) ,这个数学符号称为大O记号(big-O notation),表示函数 T(n) 的 渐近上界(asymptotic upper bound)

时间复杂度分析本质上是计算“操作数量T(n) ”的渐近上界,它具有明确的数学定义。

如下图所示,计算渐近上界就是寻找一个函数 f(n) ,使得当 n 趋向于无穷大时, T(n) 和 f(n) 处于相同的增长级别,仅相差一个常数项 c 的倍数。

最差、最佳、平均时间复杂度

算法的时间效率往往不是固定的,而是与输入数据的分布有关

假设输入一个长度为 的数组 nums ,其中 nums 由从 至 的数字组成,每个数字只出现一次;但元素顺序是随机打乱的,任务目标是返回元素的索引。我们可以得出以下结论。

  • nums = [?, ?, ..., 1] ,即当末尾元素是 1 时,需要完整遍历数组,达到最差时间复杂度O(n\O
  • nums = [1, ?, ?, ...] ,即当首个元素为时,无论数组多长都不需要继续遍历,达到最佳时间复杂度 \Omega(1)

“最差时间复杂度”对应函数渐近上界,使用大O记号表示。

相应地,“最佳时间复杂度”对应函数渐近下界,用 \Omega 记号表示:

值得说明的是,我们在实际中很少使用最佳时间复杂度,因为通常只有在很小概率下才能达到,可能会带来一定的误导性。而最差时间复杂度更为实用,因为它给出了一个效率安全值,让我们可以放心地使用算法。

从上述示例可以看出,最差时间复杂度和最佳时间复杂度只出现于“特殊的数据分布”,这些情况的出现概率可能很小,并不能真实地反映算法运行效率。相比之下,平均时间复杂度可以体现算法在随机输入数据下的运行效率,用\Theta记号来表示。

对于部分算法,我们可以简单地推算出随机数据分布下的平均情况。比如上述示例,由于输入数组是被打乱的,因此元素 1 出现在任意索引的概率都是相等的,那么算法的平均循环次数就是数组长度的一半 ,平均时间复杂度为\Theta(n/2)=\Theta(n)。

但对于较为复杂的算法,计算平均时间复杂度往往比较困难,因为很难分析出在数据分布下的整体数学期望。在这种情况下,我们通常使用最差时间复杂度作为算法效率的评判标准。

总结:

  • 最差时间复杂度用O表示(读作:big O)
  • 最佳时间复杂度用\Omega表示
  • 平均时间复杂度用\Theta表示

声明:本文内容来自于开源项目 Hello 算法,更多资源请移步学习。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Kafka消息队列python开发环境搭建
  • 微软的vscode和vs2022快捷键官网链接
  • 【漏洞复现】Rejetto HTTP文件服务器——远程命令执行(CVE-2024-23692)
  • 微信小程序加载动画文件
  • html(抽奖设计)
  • Qt 多语言
  • 解决spring boot中使用拦截器导致swagger文档无法访问
  • 数据库内核研发学习之路(三)创建postgres内置函数
  • Linux 安装多个jdk,切换使用
  • OPC通信从入门到精通_2_OPC通信详解和C#客户端编程(OPC基础概念;OPC通信仿真(KepServer作为OPC服务器;使用Modbus Slave和另外软件仿真2个PLC设备);C#程序)
  • Android使用AndServer在安卓设备上搭建服务端(Java)(Kotlin)两种写法
  • 大语言模型LLM
  • 详解python基本语法
  • 每日一练——第四题
  • vue自制表格
  • 9月CHINA-PUB-OPENDAY技术沙龙——IPHONE
  • [ JavaScript ] 数据结构与算法 —— 链表
  • CentOS 7 修改主机名
  • iOS 系统授权开发
  • Java到底能干嘛?
  • Js基础知识(一) - 变量
  • MySQL QA
  • Redis在Web项目中的应用与实践
  • 阿里云ubuntu14.04 Nginx反向代理Nodejs
  • 构建二叉树进行数值数组的去重及优化
  • 如何使用 OAuth 2.0 将 LinkedIn 集成入 iOS 应用
  • 树莓派 - 使用须知
  • 跳前端坑前,先看看这个!!
  • 策略 : 一文教你成为人工智能(AI)领域专家
  • ​ssh免密码登录设置及问题总结
  • ​学习笔记——动态路由——IS-IS中间系统到中间系统(报文/TLV)​
  • #!/usr/bin/python与#!/usr/bin/env python的区别
  • #HarmonyOS:Web组件的使用
  • (04)odoo视图操作
  • (06)Hive——正则表达式
  • (06)金属布线——为半导体注入生命的连接
  • (2)STM32单片机上位机
  • (39)STM32——FLASH闪存
  • (Bean工厂的后处理器入门)学习Spring的第七天
  • (C语言)求出1,2,5三个数不同个数组合为100的组合个数
  • (PADS学习)第二章:原理图绘制 第一部分
  • (poj1.3.2)1791(构造法模拟)
  • (PyTorch)TCN和RNN/LSTM/GRU结合实现时间序列预测
  • (剑指Offer)面试题41:和为s的连续正数序列
  • (亲测成功)在centos7.5上安装kvm,通过VNC远程连接并创建多台ubuntu虚拟机(ubuntu server版本)...
  • (十二)devops持续集成开发——jenkins的全局工具配置之sonar qube环境安装及配置
  • (详细版)Vary: Scaling up the Vision Vocabulary for Large Vision-Language Models
  • (原创) cocos2dx使用Curl连接网络(客户端)
  • (转)Unity3DUnity3D在android下调试
  • *(长期更新)软考网络工程师学习笔记——Section 22 无线局域网
  • ***微信公众号支付+微信H5支付+微信扫码支付+小程序支付+APP微信支付解决方案总结...
  • .gitignore文件设置了忽略但不生效
  • .naturalWidth 和naturalHeight属性,
  • .NetCore+vue3上传图片 Multipart body length limit 16384 exceeded.
  • .net后端程序发布到nignx上,通过nginx访问