算法的时间与空间复杂度

news2024/10/7 14:22:33

算法是指用来操作数据、解决程序问题的一种方法。对于同一问题,使用不同的算法,也许最终结果是一样的,但在过程中消耗的资源和时间却会有很大的区别。

那我们该如何去衡量不同算法之间的优劣呢?主要还是从算法所占用的【时间】和【空间】两个维度去考量。

  • 时间维度:是指执行当前算法所消耗的时间,我们通常用【时间复杂度】来描述;
  • 空间维度:是指执行当前算法所需要占用多少内存空间,我们通常用【空间复杂度】来描述。

因此,评价一个算法的效率主要是看它的时间复杂度和空间复杂度情况。然而,有的时候时间和空间却又是鱼和熊掌不可兼得,那我们就需要从从中去取一个平衡点。

下面我来分别介绍一下【时间复杂度】和【空间复杂度】的计算方式。

一、时间复杂度

我们想要知道一个算法的【时间复杂度】,很多人首先想到的方法就是把这个算法程序运行一遍,那么它所消耗的时间就自然而然知道了。

这种方式可以吗?当然可以,不过它有很多弊端。

这种方式很容易受运行环境影响,在性能高的机器上跑出来的结果与性能低的机器上跑出来的结果相差会很大。而且对测试时使用的数据规模也有很大关系。再者,我们在写算法的时候,还没有办法完整的去运行呢。

因此,另一种更为通用的方法就出来了:【大O符号表示法】,即T(n)=O(f(n))。

我们先来看个例子:

for (i=1; i <=n; i++)
{
    j = i;
    j++;
}

通过【大O表示法】,这段代码的时间复杂度为O(n),为什么呢?

在大O表示法中,时间复杂度的公式是:T(n)=O(f(n)),其中f(n)表示每行代码执行次数之和,而O表示正比例关系,这个公式的全程是:算法的渐进时间复杂度

我们继续看上面的例子,假设每行执行时间都是一样的,我们用1颗粒时间来表示,那么这个例子的第一行好事是1个颗粒时间,第三行的执行时间是n个颗粒时间,第四行的执行时间也是n个颗粒时间(第二行和第五行是符号,暂时忽略),那么总时间就是T(n)=(1+2n)*颗粒时间,从这个结果可以看出,这个算法的耗时是随着n的变化而变化,因此,我们可以简化这个算法的时间复杂度表示为:T(n)=O(n)。

为什么可以去简化呢,因为大O表示法并不是 用于来真实代表算法的执行时间的,它是哟弄个来表示代码执行时间的增长变化趋势的。

所以上面的例子中,如果n无限大的时候,T(n)=time(1+2n)中的常量1就没有意义了,倍数2也意义不大。因此直接简化为T(n)=O(n)就可以了。

常见的时间复杂度量级有:

  • 常熟阶O(1)
  • 对数阶O(logN)
  • 线性阶O(n)
  • 线性对数阶O(nlogN)
  • 平方阶O(n^{2})
  • 立方阶O(n^{3})
  • k次方阶O(n^{k}n^{k})
  • 指数阶O(2^{n})

从上至下依次的时间复杂度越来越大,执行效率越来越低。

下面选取一些较为常用的来讲解游戏啊(没有严格按照顺序):

1. 常数阶O(1)

无论代码执行了多少行,只要是没有循环等复杂结构,那这个代码的时间复杂度就都是O(1),如:

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

上述代码在执行的时候,它消耗的时间并不随着某个变量的增长而增长,那么无论这个代码有多长,即使几万几十万行,都可以用O(1)来表示它的时间复杂度。

2. 线性阶O(n)

这个在最开始的代码示例中就讲解过了,如:

for (i = 1; i <= n; i++)
{
    j = i;
    j++;
}

这段代码,for循环里面的代码会执行n遍,因此它消耗的时间是随着n的变化为变化的,因此这类代码都可以用O(n)来表示它的时间复杂度。

3. 对数阶O(logN)

还是先来看代码:

int i = 1;
while(i < n)
{
    i = i * 2;
}

从上面代码可以看到,在while循环里面,每次都将i乘以2,乘完以后i距离n就越来越近了。我们试着求解一下,假设x次之后,i就大于n了,此时这个循环就退出了,也就是说2^{x}=n,那么x=\log_{2}n,也就是说循环\log_{2}n次以后,这个代码就结束了。因此这个代码的时间复杂度为:O(\log n)

4. 线性对数阶O(nlogN)

线性对数阶O(nlogN)其实非常容易理解,将时间复杂度O(log(N))的代码循环n遍的话,那么它的时间复杂度就是nO(logN),也就是O(nlogN)。

就拿上面的代码加一点修改来举例:

for(m = 1; m <= n; m++)
{
    i = 1;
    while(i < n)
    {
        i = i * 2;    
    }
}

5. 平方阶O(n^{2})

平方阶就更容易理解了,如果把O(n)的代码再嵌套循环一遍,它的时间复杂度就是O(n^{2})了。

举例:

for (x=1; x<=n; x++)
{
    for (i=1; i<=n; i++) 
    {
        j = i;
        j++;    

    }
}

这段代码其实就是嵌套了两层n循环,它的时间复杂度就是O(n*n),即O(n^{2})

如果将其中一层循环的n改成m,即:

for (x=1; x<=m; x++)
{
    for (i=1; i<=n; i++) 
    {
        j = i;
        j++;    

    }
}

那么它的时间复杂度就变成了O(m*n)

6. 立方阶O(n^{3})、k次方阶O(n^{k})

参考上面的O(n^{2})去理解就好了,O(n^{3})相当云三层n循环,其它的类似。

除此之外,其实还有平均时间复杂度、均摊时间复杂度、最坏时间复杂度、最好时间复杂度的分析方法,有点复杂,这里就不展开了。

二、空间复杂度

既然时间复杂度不是用来计算程序具体耗时的,那么我也应该明白,空间复杂度也不是用来计算程序实际所占用的空间的。

空间复杂度是对一个算法在运行过程中临时占用存储空间大小的一个量度,同样反映的是一个趋势,我们用S(n)来定义。

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

1. 空间复杂度O(1)

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

举例:

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

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

2. 空间复杂度O(n)

我们先看一个代码:

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

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

以上,就是对算法的时间复杂度和空间复杂度基础的分析,欢迎大家一起交流。

算法的时间与空间复杂度(一看就懂)

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

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

相关文章

Anaconda+CUDA+CUDNN+Pycharm+Pytorch安装教程(第一节 Anconda安装)

1.选择和对应的anconda版本 官网地址&#xff1a;Index of / (anaconda.com) 下载地址&#xff1a;Index of /anaconda/archive/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror 2.安装流程 (1)下载安装包 (2)点击next &#xff08;3&#xff09;点击I agree &a…

MySQL--联合索引应用细节应用规范

目录 一、索引覆盖 1.完全覆盖 2.部分覆盖 3.不覆盖索引-where条件不包含联合索引的最左则不覆盖 二、MySQL8.0在索引中的新特性 1.不可见索引 2.倒序索引 三、索引自优化--索引的索引 四、Change Buffer 五、优化器算法 1.查询优化器算法 2.设置算法 3.索引下推 …

【Java】/*类和对象(上)*/

目录 一、什么是类&#xff0c;什么是对象 二、类和对象的关系 三、学习类和对象的目的 四、怎样创建一个类 4.1 语法形式 4.2 创建示例 示例一&#xff1a;日期对象 示例二&#xff1a;小狗对象 示例三&#xff1a;学生对象 4.3 注意事项 4.4 修改public修饰的主类…

css卡片翻转 父元素翻转子元素不翻转效果

css卡片翻转 父元素翻转子元素不翻转效果 vue <div class"moduleBox"><div class"headTitle"><span class"headName">大额案例</span></div><div class"moduleItem"><span class"module…

java 拦截器-用户无操作超时退出利用Redis

1、授权过滤&#xff0c;只要实现AuthConfigAdapter接口 2、利用Redis token超时时间&#xff0c;用户访问后台续时 效果 Component public class AuthFilter implements Filter {private static Logger logger LoggerFactory.getLogger(AuthFilter.class);Autowiredprivat…

《python编程从入门到实践》day39

# 昨日知识点回顾 创建主页、继承模版、显示特定主题页面 # view.py from django.shortcuts import render# 导入所需数据相关联的模型 from .models import Topic# Create your views here. def index(request):"""学习笔记的主页"""#…

GB报文中的Cseq值的注意点

一、 问题现象 【问题现象】NVR使用GB接三方平台发现倍速回放时&#xff0c; 【现场拓扑】现场拓扑如下 &#xff08;1&#xff09; NVR侧使用家用宽带的方式&#xff0c;通过国标跨公网接入三方平台。 图1.1&#xff1a;网络拓扑 二、 抓包分析 INVITE sip:420000004013200…

ABC354学习笔记

高桥有一棵植物&#xff0c;这个植物在第 0 0 0 天时高度为 0 c m 0\,\mathrm{cm} 0cm&#xff0c;此后的第 i i i 天&#xff0c;他的植物会增高 2 i c m 2^i\,\mathrm{cm} 2icm。 高桥身高为 H c m H\,\mathrm{cm} Hcm。 高桥想知道在第几天&#xff0c;他的植物的高度会…

grpc、多集群、多租户

gRPC和服务发现 一个A high-performance, open-source universal RPC framework&#xff0c;高性能、开源的通用 RPC 框架。使用protobuf 语言基于文件定义服务&#xff0c;通过 proto3 工具生成指定语言的数据结构、服务端接口以及客户端 Stub。移动端上面则是基于标准的 HTTP…

专业渗透测试 Phpsploit-Framework(PSF)框架软件小白入门教程(十三)

本系列课程&#xff0c;将重点讲解Phpsploit-Framework框架软件的基础使用&#xff01; 本文章仅提供学习&#xff0c;切勿将其用于不法手段&#xff01; 接上一篇文章内容&#xff0c;讲述如何进行Phpsploit-Framework软件的基础使用和二次开发。 我们&#xff0c;继续讲一…

如何将前端项目打包并部署到不同服务器环境

学习源码可以看我的个人前端学习笔记 (github.com):qdxzw/frontlearningNotes 觉得有帮助的同学&#xff0c;可以点心心支持一下哈&#xff08;笔记是根据b站尚硅谷的前端讲师【张天禹老师】整理的&#xff0c;用于自己复盘&#xff0c;有需要学习的可以去b站学习原版视频&…

three.js判断物体在人的前面,还是后面

three.js判断物体在人的前面&#xff0c;还是后面 const player new THREE.Vectors(10, 0, 5); const mesh new THREE.Vectors(15, 0, 6);上面&#xff0c;两个变量分别表示&#xff0c;玩家的位置&#xff0c;物体的位置。 从这发现&#xff0c;当玩家和物体的角度关系 小…

网络协议——RTSP(简介、搭建RTSP服务器)

一、简介 1、什么是RTSP RTSP&#xff08;Real-Time Streaming Protocol&#xff0c;实时流传输协议&#xff09;是一种网络应用协议&#xff0c;旨在用于在互联网上进行娱乐和通信的实时流媒体的控制。它允许客户端远程控制媒体服务器上的流媒体播放&#xff0c;例如播放、暂…

决定新泽西州版图的关键历史事件

决定新泽西州版图的关键历史事件 1. *民地建立&#xff1a;1664年&#xff0c;新泽西成为英国*民地。该地区原为荷兰*民地的一部分&#xff0c;但同年根据英王查理二世的赐予&#xff0c;转归给了他的兄弟约克公爵&#xff08;后来的詹姆士二世&#xff09;&#xff0c;之后又被…

Matlab 结构光相移法(单频多相)

文章目录 一、简介1、基于点的测距2、基于条纹的测距二、条纹编码2.1 二进制编码2.2相移法三、实现代码参考文献一、简介 在介绍相移法之前,我们需要先了解一下为啥会有相移法,了解了其来龙去脉,则更容易去应用它。 1、基于点的测距 首先我们从点的测距开始,这有点类似于立…

C++笔试强训day33

目录 1.跳台阶扩展问题 2.包含不超过两种字符的最长子串 3.字符串的排列 1.跳台阶扩展问题 链接https://www.nowcoder.com/practice/953b74ca5c4d44bb91f39ac4ddea0fee?tpId230&tqId39750&ru/exam/oj 我是用动态规划解决的&#xff1a; #include <iostream>…

Oracle 并行和 session 数量的

这也就是为什么我们指定parallel为4&#xff0c;而实际并行度为8的原因。 insert create index&#xff0c;发现并行数都是加倍的 Indexes seem always created with parallel degree 1 during import as seen from a sqlfile. The sql file shows content like: CREATE INDE…

【傻呱呱】python安装phook3(Windows端)

前期准备 swig程序Visual Studio C 构建工具 配置swig程序 将下载好的“swig-4.2.1”压缩包解压到C盘从C盘打开“swig-4.2.1”文件夹并复制文件夹路径 在开始菜单里搜索“环境变量”&#xff0c;点击“编辑系统环境变量” 点击“环境变量” 找到“path”并双击 点击“新建” …

K8S认证|CKA题库+答案| 13. sidecar 代理容器日志

目录 13、使用 sidecar 代理容器日志 CKA v1.29.0模拟系统 下载试用 题目&#xff1a; 开始操作&#xff1a; 1&#xff09;、切换集群 2&#xff09;、生成yaml文件 3&#xff09;、官网找模板 4&#xff09;、编辑yaml文件 5&#xff09;、应用yaml文件 ​6&…

吉林大学软件工程简答题整理

1.6种软件过程模型列举&#xff0c;及优缺点&#xff08;每个都从时间、质量、过程、本身特点去考虑&#xff09; 瀑布模型 优点缺点V模型 优点&#xff1a;缺点&#xff1a; 原型模型 优点&#xff1a;演化模型 建增模型 优点缺点螺旋模型 优点缺点喷泉模型 RUP、敏捷工程、…