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

数据结构学习篇(4)---算法的时间复杂度

由于现在计算机的储存在硬件上能得到很好的解决,所以时间复杂度较空间复杂度更受关注。

1.1 时间复杂度的概念

时间复杂度的定义:在计算机科学中,算法的时间复杂度是一个函数,它定量描述了该算法的运行时间。一 个算法执行所耗费的时间,从理论上说,是不能算出来的,只有你把你的程序放在机器上跑起来,才能知道。但是我们需要每个算法都上机测试吗?是可以都上机测试,但是这很麻烦,所以才有了时间复杂度这个分析方式。一个算法所花费的时间与其中语句的执行次数成正比例,算法中的基本操作的执行次数,为算法的时间复杂度

即:找到某条基本语句与问题规模N之间的数学表达式,就是算出了该算法的时间复杂度。

实际中我们计算时间复杂度时,我们其实并不一定要计算精确的执行次数,而只需要大概执行次数,那么这里我们使用大O的渐进表示法。那么对于上面这个代码的时间复杂度为O(N^2);因为cpu的计算速度非常快,所以就没有必要考虑N取值很小的情况,这种情况讨论不同算法的时间复杂度是没有意义的,因为这时他们都属于同一个层次,看不出差别,所以只针对N很大的情况才有时间复杂度这一说法,以此用来计算算法属于哪个量级。

从这个例子就可以看出,对于N=10000000的循环操作,在release版本下的运行时间甚至达不到0ms(比0ms还短的时间),这也就看出只有在N的取值很大情况下才能讨论时间复杂度。

1.2 大O的渐进表示法

本质:用于表示算法的时间复杂度(执行次数)属于哪个量级。

  1. 常数量级:统一用O(1)表示
  2. 非常数量级:用表达式中的最高项表示,如:O(N^2);如果最高项包含系数,要去除系数,因为提到时间复杂度的N值肯定是非常大的,有无系数都不影响N是一个很大的值,所以没有必要加上系数。(用数学中趋近于无穷的角度去看待这个问题)

注:对于涉及到对数的复杂度时,logN指的是以2为底的对数,这里的2被省略了,但是如果底数为其他数字则不能省略。

通过上面我们会发现大O的渐进表示法去掉了那些对结果影响不大的项,简洁明了的表示出了执行次数。

另外有些算法的时间复杂度存在最好、平均和最坏情况:

  1. 最坏情况:任意输入规模的最大运行次数(上界)
  2. 平均情况:任意输入规模的期望运行次数
  3. 最好情况:任意输入规模的最小运行次数(下界)

例如:在一个长度为N数组中搜索一个数据x:

  1. 最好情况:循环1次找到
  2. 最坏情况:循环N次找到
  3. 平均情况:循环N/2次找到

实际中一般情况关注的是算法的最坏运行情况,所以数组中搜索数据时间复杂度为O(N)

1.3 例题分析

例题1:

  • 思路1:先排序,再依次查找,如果下个值不等于前一个值加1,那么下一个值就是消失的数字。如果使用冒泡排序,时间复杂度为O(N^2);如果使用快速排序,时间复杂度为O(N*logN),都不满足题目要求
  • 思路2:计算出完整数组中的总数值之和,如何减去nums数组中的每个数值,剩下的数值就是消失的数字,时间复杂度为O(N)。

  • 思路3:利用异或的性质:相同为0,不同为1来解决问题,时间复杂度为O(N)

例题2:

  • 思路1:暴力解法:依次将数组末尾的数字移到最前端。

说明:这里的k和N(元素个数)是存在关系的:当k除以N的余数不为0时,说明是要进行轮转操作的,当余数为0时,说明不需要进行轮转操作:

  1. 最好情况:k%N=0:不需要进行轮转
  2. 最坏情况:k%N=N-1:需要进行的最大轮转次数为N-1

所以这个思路的时间复杂度为O(K*N)=O(N^2),显然不满足要求

  • 思路2:

很显然,时间复杂度为O(N),满足要求。

1.4 更为复杂的复杂度分析

上面两个例题其实可以直接通过循环的次数看出时间复杂度为多少,但是对于一些更为复杂的循环,是不能单纯通过看循环次数就算出时间复杂度的,而是要通过算法的本质思想去计算相应的时间复杂度。

比如这个二分查找算法:

单纯通过看循环次数并不能直接得出时间复杂度为多少,要从算法思想的角度去计算:

所以对于这个算法的时间复杂度就是O(logN)。

补充:二分查找相对于暴力解法来说能大大降低时间复杂度:

但是二分查找也存在一定的缺点:

  1. 要先进行排序才能进行二分查找;
  2. 二分查找属于数组结构,不方便进行数据插入或删除。
http://www.cnnetsun.cn/news/53746.html

相关文章:

  • DOM Element:深入理解与操作
  • 深度解析 Flutter 路由管理:从原生路由到 AutoRoute 的优雅升级与性能优化
  • Turnitin系统查英文AI率多少为正常?报告显示星号*%怎么办?
  • 暖通净化空调恒温恒湿项目:PLC 与触摸屏上位机程序探秘
  • 第30章 Shell 正则表达式实战:精准匹配字符串、日志与配置项
  • 音视频学习(七十二):视频压缩:分块与预处理
  • AMD Ryzen性能调优:快速掌握处理器调试工具的使用技巧
  • 深蓝词库转换:轻松打通全平台输入法数据壁垒
  • (新卷,200分)- 最小传输时延Ⅱ(Java JS Python)
  • OpenHarmony AI人脸识别与手势控制系统开发指南
  • 新一代空间感知驱动的军工仓库与硐室透明化管控技术研究
  • Sketch MeaXure插件:设计师必备的智能标注工具
  • 强化学习Q-learning求最优策略
  • 你对电脑上的【Fn】熟悉多少
  • 计及N-k安全约束的含光热电站电力系统优化调度模型【IEEE14节点、118节点】附Matlab代码
  • 计及需求响应的粒子群算法求解风能、光伏、柴油机、储能容量优化配置附Matlab代码
  • conda使用详细指南
  • 豆包与DeepSeek底层大模型的深度解析:技术架构、设计理念与生态分野
  • Linux系统中的socket激活:先创建监听端口,后启动程序
  • 从零解决pyproject.toml构建失败的实战指南
  • Redis Lua脚本入门:从零写出你的第一个原子操作
  • 旧机转手不再慌!电子产品信息清除新国标落地,核心技术逻辑全解析
  • 安全体验馆好用供应商
  • 第二章——数据分析场景之Python数据可视化:用Matplotlib与Seaborn绘制洞察之图
  • 【Java毕设全套源码+文档】基于springboot的高校毕业生离校管理系统小程序设计与实现(丰富项目+远程调试+讲解+定制)
  • 如何用AI工具jstat优化Java应用性能分析
  • 【Java毕设全套源码+文档】基于springboot的高校毕业生信息管理系统的设计与实现(丰富项目+远程调试+讲解+定制)
  • Day 38 GPU训练及类的call方法
  • 【Python实战】火爆全网的“隔空手势画板”是如何实现的?教你用OpenCV+MediaPipe复刻钢铁侠黑科技!
  • 【学习笔记】如果打造可复现、可评测、可迭代的AI技术体系