【时间复杂度和空间复杂度之间的故事】

【时间复杂度和空间复杂度之间的故事】

      • 一.前言
  • 二.时间复杂度
      • 定义
      • 时间复杂度的计算规则
      • 习题
  • 三.空间复杂度
      • 定义
      • 计算方法
      • 习题
      • 空间复杂度 O(1)
      • 空间复杂度 O(n)

本文主要讲解关于时间复杂度与空间复杂度
😀😃😁😁😇😇
在这里插入图片描述

😀😃😁😁😇😇

一.前言

时间复杂度主要衡量的是一个算法的运行速度,而空间复杂度主要衡量一个算法所需要的额外空间。在计算机发展的早期,计算机的存储容量很小,所以对空间复杂度很是在乎。但是随着计算机行业的迅速发展,计算机的存储容量已经达到了很高的程度。所以我们如今已经不需要再特别关注一个算法的空间复杂度。这就是为什么我们大多时候听到的是时间复杂度,而很少听到空间复杂度的原因。

二.时间复杂度

定义

  1. 时间复杂度就是用来方便开发者估算出程序的运行时间
  2. 我们该如何估计程序运行时间呢,我们通常会估计算法的操作单元数量,来代表程序消耗的时间,
    这里我们默认CPU的每个单元运行消耗的时间都是相同的。
  3. 假设算法的问题规模为n,那么操作单元数量便用函数f(n)来表示
  4. 随着数据规模n的增大,算法执行时间的增长率和f(n)的增长率相同,这称作为算法的渐近时间复杂度,简称时间复杂度,记为 O(f(n))
  5. 这里就要说一下这个大O,什么是大O呢,很多同学说时间复杂度的时候都知道O(n),O(n^2),但说不清什么是大O,算法导论给出的解释:大O用来表示上界的,当用它作为算法的最坏情况运行时间的上界,就是对任意数据输入的运行时间的上界。
    😀😃😁😁😇😇

时间复杂度的计算规则

  • 基本操作即只有常数项,认为其时间复杂度为O(1)
  • 顺序结构,时间复杂度按加法进行计算
  • 循环结构,时间复杂度按乘法进行计算
  • 分支结构,时间复杂度取最大值
  • 在没有特殊说明时,我们所分析的时间复杂度都是指最坏时间复杂度
  • 判断一个算法效率时,往往只需要关注操作数量的最高次项,其他次要项和常数项可以忽略

注:递归算法的时间复杂度 = 递归的次数 * 每次递归函数中的次数。

习题

例一

int result = 100; //运行程序只执行一次  result ++ ;  //执行一次System.out.println ("Hello!"+result);

上面算法的运行的次数的函数为f(n)=3,根据推导大O阶的规则1,每次运行程序每条语句执行一次,所以这个算法的时间复杂度仍旧是O(1),我们可以称之为常数阶。

例二

void fun4(int N) {int count = 0; for (int k = 0; k < 100; k++) {++count;}printf("%d\n", count);
}

fun3的基本操作的执行了100次,通过推导大O阶方法知道,时间复杂度为O(1),也就是执行次数为常数。

例三

for(int i=0;i<n;i++){System.out.println(result[i]);  //执行一次}

上面算法循环体中的代码执行了n次,因此时间复杂度为O(n),实际上,在for循环里面的所有时间复杂度为O(1)的语句总的时间复杂度都是O(n)。

例四

int result=1;while(result<n){result=result*2; //时间复杂度为O(1)}

可以看出上面的代码, result=result*2; 随着result每次乘以2后,都会越来越接近n,当result大于等于n时就会退出循环(限制条件)。

如果循环的次数为T,所以2^T=n于是T=log₂n,因此得出这个算法的时间复杂度为O(logn)。

例五

//二分查找法
int BinarySearch(int* a, int  n, int x) {assert(a);int begin = 0;int end = n - 1;while (begin < end) {int mid = ((end - begin) >> 1) + begin; //计算end与begin的中间值,右移1位相当于除以2if (a[mid] < x) {begin = mid - 1;}else if(a[mid]>x){end = mid;}else {return mid;}}return -1;
}

时间复杂度为:O(logN)。分析如下:

第一次查找:在长度为N的数组中查找值,取中间值进行比较
第二次查找:在长度为N/2的数组中查找值,取中间值进行比较
第三次查找:在长度为N/(2^2)的数组中查找值,取中间值进行比较
第logN次查找:在长度为N/(2^logN)的数组中查找值,即在长度为1的数组中查找,无论是否找到均跳出循环,结束查找

例六

  for(int i=0;i<n;i++){       for(int j=0;j<n;j++){     System.out.println(result[i][j]);  //执行一次     }     }

这是一个循环嵌套的语句,很明显内层循环的时间复杂度在讲到线性阶时就已经得知是O(n),又经过了外层循环n次,那么这段算法的时间复杂度则为O(n²)。

例七

void fun(int n){int i,j,x=0;for(i=1;i<n;i++){for(j=n;j>=i+1;j--){x++;}}
}

在这里插入图片描述

例八

void fun(int n){int i=0;while(i*i*i<=n){i++;}
}

在这里插入图片描述
例九

// 多个复杂度组合for(int i=0;i<n;i++){   for(int j=0;j<n;i++){ System.out.println(result[i][j]);  //执行一次 } 
}for(int i=0;i<n;i++){  System.out.println(result[i]);  //执行一次 
}

对于顺序执行的语句或者算法,总的时间复杂度等于其中最大的时间复杂度。所以对于以上的代码,时间复杂度为O(n²)。

例十

// 多个复杂度组合
if(flag){ for(int i=0;i<n;i++){  for(int j=0;j<n;i++){ System.out.println(result[i][j]);  //执行一次 } } 
}else{ for(int i=0;i<n;i++){   System.out.println(result[i]);  //执行一次 } 
}

对于条件判断语句,总的时间复杂度等于其中时间复杂度最大的路径的时间复杂度。所以对于以上的代码,时间复杂度为O(n²)。
在这里插入图片描述

三.空间复杂度

定义

既然时间复杂度不是用来计算程序具体耗时的,那么我也应该明白,空间复杂度也不是用来计算程序实际占用的空间的。
空间复杂度是对一个算法在运行过程中临时占用存储空间大小的一个量度,同样反映的是一个趋势,我们用 S(n) 来定义。
😀😃😁😁😇😇

计算方法

空间复杂度是对一个算法在运行过程中临时占用存储空间大小的量度。空间复杂度不是程序占用了多少字节的空间,因为这个也没太大意义,所以空间复杂度算的是变量的个数。空间复杂度计算规则基本跟时间复杂度类似,也使用大O渐进表示法。

习题

空间复杂度比较常用的有:O(1)、O(n)、O(n²),我们下面来看看:

空间复杂度 O(1)

如果算法执行所需要的临时空间不随着某个变量n的大小而变化,即此算法空间复杂度为一个常量,可表示为 O(1)

int i = 1;
int j = 2;
++i;
j++;
int m = i + j;

代码中的 i、j、m 所分配的空间都不随着处理数据量变化,因此它的空间复杂度 S(n) = O(1)

空间复杂度 O(n)

int[] m = new int[n]
for(i=1; i<=n; ++i)
{j = i;j++;
}

这段代码中,第一行new了一个数组出来,这个数据占用的大小为n,虽然有循环,但没有再分配新的空间,因此,这段代码的空间复杂度主要看第一行即可,即 S(n) = O(n).

例一

//计算冒泡排序函数的空间复杂度
void BubbleSort(int* a, int N)
{assert(a);for (int i = 0; i < N; i++){int exchange = 0;for (int j = 0; j < N - 1 - i; j++){if (a[j]>a[j + 1]){int tmp = a[j];a[j] = a[j + 1];a[j + 1] = tmp;exchange = 1;}}if (exchange == 0)break;}
}

冒泡排序函数中使用了常数个额外空间(即常数个变量),所以用大O的渐进表示法表示冒泡排序函数的空间复杂度为O(1) 。

例二

//计算阶乘递归函数的空间复杂度
long long Factorial(size_t N)
{return N < 2 ? N : Factorial(N - 1)*N;
}

阶乘递归函数会依次调用Factorial(N),Factorial(N-1),…,Factorial(2),Factorial(1),开辟了N个空间,所以空间复杂度为O(N) 。

注:递归算法的空间复杂度通常是递归的深度(即递归多少层)。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/13524.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

FastAPI单元测试:使用TestClient轻松测试你的API

当使用FastAPI进行单元测试时&#xff0c;一个重要的工具是TestClient类。TestClient类允许我们模拟对FastAPI应用程序的HTTP请求&#xff0c;并测试应用程序的响应。这使我们能够在不启动服务器的情况下对API进行全面的测试。 下面我将详细讲解TestClient的使用方法和常见操作…

10大桌面软件前端框架,那个是您的最爱呢?

桌面端前端框架是用于构建桌面应用程序的前端框架&#xff0c;以下是一些常用的桌面端前端框架&#xff1a; 1. Electron&#xff1a; Electron是一个开源的桌面应用程序开发框架&#xff0c;可以使用HTML、CSS和JavaScript构建跨平台的桌面应用程序&#xff0c;例如VS Code、…

2024 年第四届长三角高校数学建模竞赛赛题B题超详细解题思路+代码分享

B题 人工智能范式的物理化学家 问题一问题二问题三问题四问题五完整代码与文档获取 B题思路详细解析分享给大家&#xff0c;还会继续更新完成具体的求解过程&#xff0c;以及全部的代码与技术文档&#xff0c;都会直接给大家分享的哦~需要完整代码直接看到最后哦 问题一 针对问…

谈谈【软件测试的基础知识,基础模型】

关于软件测试的基本概念和基本模型 前言一个优秀的测试人员具备的素质关于需求测试用例软件错误(BUG)概念开发模型瀑布模型&#xff08;Waterfall Model&#xff09;螺旋模型&#xff08;Spiral Model&#xff09; 前言 首先,什么是软件测试? 通俗来讲:软件测试就是找BUG&…

【配置】雷池WAF社区版安装

官方文档点击跳转 什么是雷池 雷池&#xff08;SafeLine&#xff09;是长亭科技耗时近 10 年倾情打造的 WAF&#xff0c;核心检测能力由智能语义分析算法驱动。 什么是 WAF WAF 是 Web Application Firewall 的缩写&#xff0c;也被称为 Web 应用防火墙。 区别于传统防火墙…

记某src通过越权拿下高危漏洞

在挖掘某SRC时&#xff0c;遇到了一个社区网站&#xff0c;社区站点是我在挖掘SRC时比较愿意遇到的&#xff0c;因为它们可探索的内容是较多的&#xff0c;幸运地&#xff0c;通过两个接口构造参数可进行越权&#xff0c;从而获得整个网站用户的信息。 图片以进行脱敏处理。在…

单词可交互的弧形文本

在一个项目中&#xff0c;要求把少儿读本做成电子教材呈现出来&#xff0c;电子书的排版要求跟纸质书一致。其中&#xff0c;英语书有个需求&#xff1a;书中有些不规则排版的文本&#xff08;如下图所示&#xff09;&#xff0c;当随书音频播放时&#xff0c;被读到的文本要求…

gin框架学习笔记(四) ——参数绑定与参数验证

参数绑定 前言 在Gin框架中我们可以利用bind来将前段传递过来的参数与结构体进行参数绑定与参数校验&#xff0c;而这bind的方式主要有以下两种: Mustbind:一般使用较少&#xff0c;因为参数校验失败会改变状态码Shouldbind&#xff1a;主要使用上的校验方法&#xff0c;校验…

Elasticsearch - HTTP

文章目录 安装基本语法索引创建索引查看索引删除索引 文档创建文档更新文档匹配查询多条件查询聚合查询映射 安装 https://www.elastic.co/downloads/past-releases/elasticsearch-7-17-0 下载完成启动bin/elasticsearch服务&#xff0c;可以在Postman调试各种请求。 基本语法…

高稳定LED驱动IC防干扰数显驱动控制器热水器LED驱动芯片VK1650 SOP16/DIP16 原厂FAE支持

产品型号&#xff1a;VK1650 产品品牌&#xff1a;永嘉微电/VINKA 封装形式&#xff1a;SOP16/DIP16 工程服务&#xff0c;技术支持&#xff01; 概述 VK1650是一种带键盘扫描电路接口的 LED 驱动控制专用芯片&#xff0c;内部集成有数据锁存器、LED 驱动、键盘扫描等电路。…

2024年职称评审流程大揭秘,顺利拿下职称

上半年时间不急&#xff0c;中旬太忙&#xff0c;没有时间&#xff0c;下半年干着急。评职称一定要趁早&#xff0c;不然卡住一个流程&#xff0c;今年就不需要评职称了。中级副高级职称评职称就像挤公交你不努力挤一把&#xff0c;就只能等下一趟下一趟。所以评职称一定要看准…

[Cocos Creator 3.5赛车游戏] 第4节 创建汽车节点

在实现汽车节点之前&#xff0c;我们要先熟悉一下少量的基本概念&#xff0c;这样才能让您更快的实现第一个汽车节点。 一、基本概念 1.什么是节点&#xff1a; 在Cocos中&#xff0c;场景是由一系列节点组成的&#xff0c;每个节点下面又可以有子节点&#xff0c;而每个节点都…

Axure RP 9 for Mac:强大的原型设计利器

Axure RP 9 for Mac是一款功能强大的原型设计工具&#xff0c;专为Mac用户打造。它支持高保真度的应用程序和网站原型设计&#xff0c;帮助用户快速创建高质量的产品原型。软件内置丰富的交互效果和动画设计选项&#xff0c;设计师可以通过简单的操作&#xff0c;为原型添加各种…

记录计全支付切换到RabbitMQ时启动报错的问题

记录计全支付切换到RabbitMQ时启动报错的问题 首先在application.yml中切换到RabbitMQ配置安装RabbitMQ、Erlang、延时插件 rabbitmq_delayed_message_exchange&#xff0c;延迟插件必装 首先在application.yml中切换到RabbitMQ配置 # 第一处rabbitmq:addresses: 127.0.0.1:56…

Winform自定义控件 —— 开关

在开始阅读本文之前&#xff0c;如果您有学习创建自定义控件库并在其他项目中引用的需求&#xff0c;请参考&#xff1a;在Visual Studio中创建自定义Winform控件库并在其他解决方案中引用https://blog.csdn.net/YMGogre/article/details/126508042 0、引言 由于 Winform 框架并…

深入探索Jetpack Compose:大前端式客户端开发实战

&#x1f482; 个人网站:【 摸鱼游戏】【神级代码资源网站】【工具大全】&#x1f91f; 一站式轻松构建小程序、Web网站、移动应用&#xff1a;&#x1f449;注册地址&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交…

(二)Jetpack Compose 布局模型

前文回顾 &#xff08;一&#xff09;Jetpack Compose 从入门到会写-CSDN博客 首先让我们回顾一下上一篇文章中里提到过几个问题&#xff1a; ComposeView的层级关系&#xff0c;互相嵌套存在的问题&#xff1f; 为什么Compose可以实现只测量一次&#xff1f; ComposeView和…

还拿B端设计经验,设计政务类系统,驴唇不对马嘴啦。

一、什么是政务类系统&#xff0c;涉及哪些领域 政务类系统是指用于政府机构或政府部门进行管理和运营的信息化系统。政务类系统的目的是提高政府工作效率、优化公共服务、加强政府与公民之间的互动和沟通。 政务类系统通常涵盖了各个方面的政府工作&#xff0c;包括但不限于以…

Media Encoder 2024 for Mac:专业的音视频编码神器

Media Encoder 2024 for Mac&#xff0c;作为Mac用户的专业音视频编码工具&#xff0c;凭借其强大的功能和用户友好的界面&#xff0c;深受专业人士的喜爱。它支持将各种格式的音视频素材转换为多种流行格式&#xff0c;如MP4、MOV、AVI等&#xff0c;满足不同的播放和发布需求…

计算机网络-DHCPv6基础

前面我们学习了IPv6地址可以通过手动配置、无状态自动配置、DHCPv6配置&#xff0c;这里简单学习下DHCPv6的知识点。 一、DHCPv6概述 DHCPv6 (Dynamic Host Configuration Protocol for IPv6) 是一种网络协议&#xff0c;设计用于IPv6网络环境中自动为网络设备分配必要的配置信…