复杂度的讲解

1.算法效率

如何衡量一个算法的好坏?从两个维度,时间和空间(算法运行的快慢,消耗的空间大不大)。因为计算机硬件领域的高速发展,如今计算机的存储量已经达到了一个很高的程度,所以现在我们一般重点关注时间复杂度,空间复杂度也就不那么被重视了。

2.时间复杂度

时间复杂度的定义:在计算机科学中,算法的时间复杂度是一个函数表达式(数学意义上的函数)。时间复杂度描述的不是算法运行的具体时间,因为一个程序的时间是没有标准的,他跟计算机的硬件有很大的关系,而一个算法的运行时间与其中语句的执行次数是成正比例的,所以时间复杂度描述的是算法中的基本操作的执行次数。

找到某条基本语句和问题规模N之间的数学表达式,就是算出了该算法的时间复杂度。比如下面这段代码:

void test(int N)
{int i = 0;int j = 0;for (i = 0; i < N; i++){for (j = 0; j < i; j++){printf("* ");}printf("\n");}
}

这个算法的基本语句就是循环中的打印星号和打印换行,打印星号的执行的次数是(0+1+2+……+N-1)=N(N-1)/2,而打印换行的执行次数为N次,所以这个算法的时间复杂度为N(N+1)/2。但是我们一般不需要准确的执行次数,只需要知道大概的次数就行了,于是就有了一种大O的渐进表示法。比如这个算法,我们一般描述它的时间复杂度就是O(N^2)

大O的渐进表示法的规则:

1.用常数1取代运行时间中的所有加法常数

2.在修改后的运行次数追踪,只保留最高阶

3.如果最高阶项系数存在且不为1,则去除这个项的常数系数。

如果表达式结果是常数,那就是O(1)

就比如上面的算法,准确的运行次数是N^2/2+N/2,首先去除加法常数,因为没有,所以不用管。如何只保留最高阶,也就是N^2/2,最高阶地系数为1/2,把系数去除,得到的就是N^2,时间复杂度就是O(N^2)。

只保留最高项是因为这个最高项是对结果产生决定性影响,就比如N^2+N,当N接近无穷大时,N^2的结果才是决定最终结果的关键因素,而N在这里起到的效果几乎可以忽略不记。

为什么最高项常数系数要去除呢?还是因为N趋近无穷大时,由于这个常数系数不管多大他都是远小于无穷大的,不会对最终结果产生太大影响,至少不会在量级上产生大的影响。

再比如下面这个算法:

int fib(int n)
{if (n == 1 || n == 2){return 1;}else{return fib(n - 1) + fib(n - 2);}
}

我们可以把这个递归的图给画出来

右边的肯定是要比左边递归的深度要小的,但是我们只用算大概的执行次数就行了,我们假设这个三角形是完整的,他的执行次数总数和就是 ( 1+2+4+……+2^n-2),最终结果的最高项肯定是2^n,所以这个算法的时间复杂度就是O(N)

int fib(int n)
{if (n == 1 || n == 2){return 1;}int a = 1;int b = 1;int ret = 1;while (n>2){ret = a + b; a = b;b = ret;n--;}return ret;
}

这个算法的时间复杂度就是O(N)

我们还可以知道一些常用的算法的时间复杂度,比如冒泡排序的时间复杂度就是O(N^2),二分查找的时间复杂度就是logN,注意,我们在时间复杂度中的log都是默认以2为底的。

3.空间复杂度

时间复杂度主要衡量一个算法的运行快慢,而空间复杂度主要衡量一个算法运行所需要的额外空间。 空间复杂度也是一个函数表达式,是对一个算法在运行过程中临时(额外)占用存储空间的大小。但是我们关注的也不是具体的内存的大小,还是因为硬件的原因,比如同一段代码,一个int类型的变量,在有的机器上他只占两个字节,而在有的机器上占四个字节,所以这个所占空间的具体的大小也是没有意义的。空间复杂度算的是变量的个数或者函数调用建立栈帧的次数或者层数(递归)。

就比如我们递归求斐波那契数的函数

我们可以将上面的每一个方块看成一个函数栈帧,但是我们要记住一点,我们调用fib(n-1)+fib(n-2)时,不是同时为这两个函数创建栈帧,而是会在fib(n-1)返回后再去调用fib(n-2),所以计算这个递归的空间复杂度看的不是调用的次数,而是递归的深度,同时,因为每次创建栈帧时栈帧的空间就已经是固定的了,也就是一个常数,在大O的渐进表示法中,加法的常数和系数的常数都是会删掉的,所以这个算法的空间复杂度就是O(N)。

在之前我们学完函数栈帧的时候就能发现,一个变量生命周期结束后,它的空间就还给了操作系统,如果我们在后面创建变量时,是有可能会重复利用这块空间的。

要记住,空间是可以重复利用的,不累积。而是就是一去不复返的,是累积的。在写算法的时候,我们尤其要注意算法的时间复杂度,必要时我们要采取以空间换时间的策略。

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

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

相关文章

微信公众号如何开通留言功能?

首先&#xff0c;我们需要了解为什么现在注册的公众号没有留言功能。这是因为所有在2018年之后注册的微信公众号都无法再自带留言功能。这一变化是根据微信的通知而实施的。自2018年2月12日起&#xff0c;微信对新注册的公众号进行了调整&#xff0c;取消了留言功能。这一决策主…

MySQL - 基础二

6、表的增删改查 CRUD : Create(创建), Retrieve(读取)&#xff0c;Update(更新)&#xff0c;Delete&#xff08;删除&#xff09; 6.1、Create 语法&#xff1a; INSERT [INTO] table_name[(column [, column] ...)]VALUES (value_list) [, (value_list)] ...value_list: v…

第十四届省赛大学B组(C/C++)子串简写

原题链接&#xff1a;子串简写 程序猿圈子里正在流行一种很新的简写方法&#xff1a; 对于一个字符串&#xff0c;只保留首尾字符&#xff0c;将首尾字符之间的所有字符用这部分的长度代替。 例如 internationalization 简写成 i18n&#xff0c;Kubernetes 简写成 K8s&#…

【SaaS,PaaS? XaaS -微参考】

介绍 以下是关于各种云服务模式的简要介绍&#xff0c;包括全称、定义、典型场景和应用&#xff1a; 缩写全称定义关键词典型场景和应用SaaSSoftware as a Service将软件以服务的形式交付给用户&#xff0c;用户通过互联网访问软件。提供软件电子邮件、在线办公套件&#xff…

JAVAEE——文件IO之文件操作

文章目录 文件的创建和销毁File概述构造方法常用的方法getAbsolutePath()exists()isDirectory()isFile()createNewFile()delete()deleteOnExit()list()listFiles()mkdir() 文件的创建和销毁 上面我们介绍了文件的读写操作那么文件的创建等的操作如何进行呢&#xff1f;这个操作…

前视声呐目标识别定位(四)-代码解析之启动识别模块

前视声呐目标识别定位&#xff08;一&#xff09;-基础知识 前视声呐目标识别定位&#xff08;二&#xff09;-目标识别定位模块 前视声呐目标识别定位&#xff08;三&#xff09;-部署至机器人 前视声呐目标识别定位&#xff08;四&#xff09;-代码解析之启动识别模块 …

C语言之分支语句和循环语句

前言 一、什么是语句&#xff1f; 二、分支语句&#xff08;选择结构&#xff09; 2.1 if语句 2.2 switch语句 三、循环语句 3.1 while循环 3.2 break与continue语句 3.3 getchar()与putchar() 3.3.1 缓冲区 3.4 for循环 3.4.1 一些for循环的变种 3.5 do...while循…

C语言中的结构体:高级特性与扩展应用

前言 结构体在C语言中的应用不仅限于基本的定义和使用&#xff0c;还包含一些高级特性和扩展应用&#xff0c;这些特性和应用使得结构体在编程中发挥着更加重要的作用。 一、位字段&#xff08;Bit-fields&#xff09; 在结构体中&#xff0c;我们可以使用位字段来定义成员…

AJAX —— 学习(二)

目录 一、利用 JSON 字符串 返回数据 &#xff08;一&#xff09;基础代码 &#xff08;二&#xff09;原理及实现 二、nodmon 工具 自动重启服务 &#xff08;一&#xff09;用途 &#xff08;二&#xff09;下载 &#xff08;三&#xff09;使用 三、IE 缓存问题 &a…

QA测试开发工程师面试题满分问答8: mysql数据库的索引定义、用途和使用场景

MySQL数据库索引是一种数据结构&#xff0c;用于提高数据库的查询效率。索引是基于表中的一个或多个列构建的&#xff0c;它们允许数据库系统快速定位和访问表中的特定数据&#xff0c;而无需扫描整个表。 索引的定义 在MySQL中&#xff0c;可以使用CREATE INDEX语句定义索引…

Linux:进程终止和等待

一、进程终止 main函数的返回值也叫做进程的退出码&#xff0c;一般0表示成功&#xff0c;非零表示失败。我们也可以用不同的数字来表示不同失败的原因。 echo $?//打印最近一次进程执行的退出码 而作为程序猿&#xff0c;我们更需要知道的是错误码所代表的错误信息&#x…

【信号与系统 - 2】傅里叶变换与反变换

1 傅里叶变换与频谱密度函数 非周期信号可以看成是 T → ∞ T\to{\infty} T→∞ 的周期信号 由于 w ↓ 2 π T ↑ w\downarrow\frac{2\pi}{T\uparrow} w↓T↑2π​&#xff0c; T T T 无限大&#xff0c;则基波频率 w w w 无限小&#xff0c;可以视为 d w dw dw 在频谱图…

电工技术学习笔记——直流电路及其分析方法

一、直流电路 电路的组成 1. 电压和电流的参考方向 电压&#xff08;Voltage&#xff09;&#xff1a;电压是电场力对电荷产生的作用&#xff0c;表示为电荷单位正电荷所具有的能量。在电路中&#xff0c;电压通常被定义为两点之间的电势差&#xff0c;具有方向性&#xff0c;…

HomePlug AV

目录 HomePlug AV的基本概念基本术语网络概念网络实例 HomePlug AV物理层&#xff08;PHY&#xff09;HomePlug AV OFDM收发器架构PHY的调制模式FC调制和ROBO调制物理层的特点OFDM频域/时域转换开窗/槽式OFDM信号和噪声PHY发送控制——信道自适应PHY帧格式&#xff08;Symbol&a…

中间件复习之-RPC框架

什么是RPC框架&#xff1f; RPC(Remote Procedure Call):远程过程调用。当多个应用部署在多个服务器上时&#xff0c;由于他们不在一个内存空间上&#xff0c;因此需要网络来进行通信&#xff0c;而RPC允许它像调用本地方法一样调用远程服务。 RPC原理 服务消费方通过RPC客户…

Unity类银河恶魔城学习记录12-3 p125 Limit Inventory Slots源代码

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili Inventory.cs using Newtonsoft.Json.Linq; using System.Collections; us…

【面试八股总结】进程(一)

参考资料 &#xff1a;小林Coding、阿秀、代码随想录 一、什么是进程&#xff1f; 1. 基本概念 进程是具有独立功能的程序在一个数据集合上运行的过程&#xff0c;是系统进行资源分配和调度的一个独立单位。 2. 进程控制块 系统通过进程控制块PCB描述进程的进本情况…

20.2k stars项目搭建私人网盘界面美功能全

Nextcloud是一套用于创建网络硬盘的客户端&#xff0d;服务器软件。其功能与Dropbox相近&#xff0c;但Nextcloud是自由及开放源代码软件&#xff0c;每个人都可以在私人服务器上安装并执行它。 GitHub数据 20.2k stars561 watching3.2k forks 开源地址:https://github.com/ne…

利用Python将TXT文件中的经纬度数据转换为JSON格式

在处理地理空间数据时&#xff0c;经常需要将数据从一种格式转换为另一种格式&#xff0c;以便于后续的分析或可视化。本文将介绍如何使用Python脚本将存储在TXT文件中的经纬度数据转换为JSON格式。 一、背景介绍 经纬度数据是地理信息系统&#xff08;GIS&#xff09;中的基…

Redis 全景图(3)--- Redis 应用于缓存

前言 这是关于 Redis 全景图的最后一篇文章。因为一次写太多会限流&#xff0c;我也是没办法&#xff0c;才分成三篇文章来写。这篇文章是关于 Redis 应用于缓存的。 其实为什么要讲这个话题呢&#xff1f; Redis 应用在很多地方呀&#xff0c;为什么一定要挑着这个话题来讲呢…