数据结构之时间复杂度空间复杂度的计算

news2024/12/23 9:09:06

数据结构:计算机如何存储数据的问题。DS关心的是如何高效的进行数据的读写。

算法:在特定的数据集上(不关心怎么进行具体数据的读写),如何利用数据完成特定的功能。算法本质上就是一系列运算的先后集合。

那么,如何评价一个算法的好坏?

从两种维度进行:时间效率与空间效率

时间复杂度:主要衡量一个算法的运行速度(不是实际计算机的运行速度,是理论值,在所有计算机上通用的描述) 

空间复杂度:主要衡量一个算法正常执行所需要的额外空间大小,不是当前数据集本身占用的空间

所谓额外空间:为了解决这个问题,新开辟的内存大小

1. 时间复杂度

不是具体的时间,在计算机领域,其实是一个数学函数。

因为不同的计算机硬件不同,相同的算法在不同的CPU,内存这些硬件上具体的执行时间都会有差异,而且差异还挺大!

那么,利用数学函数,描述一个算法的基本操作的执行次数,就是所谓的时间复杂度

 在函数中,基本的执行语句可以不统计,基本语句和变量N毫无关系,时间复杂度看重的是执行次数和传入的变量之间的关系

使用大O渐进表示法(数学函数,表示渐进函数)来描述一个算法的时间效率。

1.1 推导大O阶的方法:

(1)用常数1来代替函数中的所有加法常数(只要是常量,常数,都会1,无论常量有多大,用1代替)

因为常数和传入数值N变量毫无关系,此算法是一个稳定的时间效率算法,和变量无关!

(2)只保留函数的最高阶项,所有的低阶省略不计

(3)若最高阶项存在且项数不为1,统一将其最高阶的项数看做1

先看最高阶在哪,低阶全部省略;若没有变量参与,统一都是常数1。

例如:F(N)=N^2+2N+10                  时间复杂度:F(N)=O(N^2)

1.2 时间复杂度评价标准

一个算法的时间复杂度存在最好、最坏、平均时间复杂度。

  • 最好:任意输入的数据,最小的执行次数(算法的下界)
  • 最坏:任意输入的数据,最大的执行次数(算法的上界)
  • 平均:任意输入的数据,平均的执行次数

eg:在长度为N的数组中,搜索一个数据x

最坏:若x刚好在数组的末尾或者不存在该数据,则需将整个数组进行遍历,执行N次才有结果

最好:若x刚好在数组首端,执行一次就能得到结果

平均:1+2+3+......+N=(1+N)*N/2(N个数据的总共查找次数)

           单个数据((1+N)*N/2)/N =N/2       时间复杂度:O(N)

衡量一个算法的时间复杂度取上界,即考虑算法的最坏情况,使用大O阶时间复杂度来描述最坏情况就是整个算法的时间复杂度。

1.3 相关例题

1. 大O阶看的是变量的最高阶,若存在多个输入变量,都需要保留各个变量的最高阶。

此时N和M都是变量,无法得知N和M谁大谁小,推导大O阶时,N和M都保留其最高阶。

时间复杂度:O(N+M)

2. N和循环次数没有关系,循环次始终为100。O(1) 和变量N无关

时间复杂度:O(1)

 3.  冒泡排序

循环次数为N^2,内外层都执行N次。时间复杂度:O(N^2)

 4. 二分查找

该循环每次不是从0--N,而是每次从区间的中间位置将区间一分为二,mid=N/2;

n/2+n/4+n/8+.....+n/16+....,要求这个执行次数,以2为底N的对数 

时间复杂度:O(logn)

 public static int binSearch(int[] arr,int value){
        int left=0;
        int right=arr.length-1;
        while(left<=right){
            int mid=(right+left)/2;
            if(value<arr[mid]){
                right=mid-1;
            }else if(value>arr[mid])
            {
                left=mid+1;
            }else{
                return mid;
            }
        }
        //抛出运行时异常,代表未找到元素(不能返回-1,因为-1也有可能为元素本身)
        throw new NoSuchElementException("没有找到该元素!");
    }

(1)原则:忽略底数(换底公式:无论底数为多少,都可以换成以10为底的)

O(logn)==>忽略底数,即:对数级别的时间复杂度

如果一个算法能够做到对数级别的时间复杂度,则是非常优秀的!

(2)如何分析一个算法是对数级别的时间复杂度?

若算法是不断的将一个变量除以一个常数:N/2,或者N/3,一直除到为1或者0,则这个算法一定是对数级别的算法O(logn),也叫折纸算法

(3)分析O(N)、O(logN)、O(N^2)随着N的不断变化,三个不同函数的变化趋势。

 二分查找在一亿的有序集合中,最坏只需要29次就能查到特定元素。

5. 关于递归算法的执行时间分析

public static int fibo(int N){
        return N<=2? N:fibo(N-2)+fibo(N-1);
    }

执行次数:将fibo函数展开,执行次数就是下图中的方框个数,也就是说,求执行次数就是求结点的总个数。 

2+4+6+8+....+..... 求二叉树的节点个数2^N+1==> 时间复杂度:O(2^N)

 public static int factor(int N){
        //1.base case
        if(N<=2){
            return N;
        }
        return N*factor(N-1);
    }

 执行次数:上述代码展开类比为:for(int i=1;i<N;i++){ int n*=i;},因此,时间复杂度为O(N)

总结:看一个递归算法的时间复杂度,就看递归展开,函数的执行次数即可!

2. 空间复杂度 

 算法执行过程中,额外开辟的空间大小。

时间复杂度描述的是算法的执行次数;

空间复杂度描述的是一个算法额外开辟的临时变量个数,也是使用大O渐进表示法。

eg:冒泡排序的空间复杂度O(1),额外开辟了一个临时变量temp。

2.1 分析空间复杂度

1. 斐波那契函数的空间复杂度

 public static int[] fibo(int N){
        int[] ret=new int[N+1];
        ret[0]=1;
        ret[1]=1;
        for (int i = 2; i<=N ; i++) {
            ret[i]=ret[i-1]+ret[i-2];
        }
        return ret;
    }

 由于函数中出现了new int[N+1];也就是说额外开辟了一个新数组,因此空间复杂度为O(N)。

2. 递归函数的空间复杂度

对于递归函数来说,每执行一次函数,就会在系统栈上产生新的栈帧,这就属于临时空间。

 public static int factor(int N){
        return N<=2?N:N*factor(N-1);
    }

也就是说观察其展开的次数。

空间复杂度:O(N)

总结:

非递归:空间复杂度就是看函数内部new了什么

递归:看函数的展开次数,每次调用一次函数,都会额外在栈上开辟栈帧空间。

一般空间复杂度最常见的为O(1)或O(N)

在题目中,出现空间复杂度要求为O(1),代表此时不能开辟新的数组且不能使用递归。

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

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

相关文章

电工-国产二极管型号、三极管型号的命名方式

根据半导体器件型号命名方法&#xff08;GB249-74&#xff09;规定&#xff0c;国产半导体由5共部分组成&#xff0c;二极管、三极管的型号命名方式也有5个部分&#xff0c;第一部分是标明晶体管数目&#xff08;二极管或是三极管&#xff09;。第二部分是三极管的材质标识&…

【ZLM】花屏现象记录

目录 事后小结 现象 tcpdump看下包的情况 移了两个摄像头到10.60.100.196 事后小结 花屏的现象&#xff0c;主要看链路时延的稳定性。 如果 ping -s 2000 ip , > 2ms已经带宽 2000*8*2/0.002s16Mbps&#xff0c;说明带宽不够&#xff0c;应该接近100Mbps左右。你可…

C#中使用Newtonsoft.Charp实现Json对象序列化与反序列化

场景 C#中使用Newtonsoft.Json实现对Json字符串的解析&#xff1a; C#中使用Newtonsoft.Json实现对Json字符串的解析_霸道流氓气质的博客-CSDN博客 上面讲的对JSON字符串进行解析&#xff0c;实际就是JSON对象的反序列化。 在与第三方进行交互时常需要封装对象&#xff0c;…

linux 防火墙iptables

iptables 是 Linux 中比较底层的网络服务&#xff0c;它控制了 Linux 系统中的网络操作&#xff0c;CentOS 中的 firewalld 和 Ubuntu 中的 ufw 都是在 iptables 之上构建的&#xff0c;只为了简化 iptables 的操作。同时&#xff0c;iptables 不仅仅是防火墙这么简单&#xff…

C/C++代码静态检测工具PC-Lint常见错误总结

目录 1、PC-Lint 概述 2、PC-lint 常见错误列举 3、PC-Lint报告的语法错误 4、总结 VC常用功能开发汇总&#xff08;专栏文章列表&#xff0c;欢迎订阅&#xff0c;持续更新...&#xff09;https://blog.csdn.net/chenlycly/article/details/124272585C软件异常排查从入门到…

看文章-做笔记

看文章-做笔记 小蓝本

想要防止视频被盗?用它给视频加水印

随着社交网络的普及&#xff0c;越来越多的人喜欢在网上分享自己制作的视频&#xff0c;但是&#xff0c;共享的视频可能会被其他人传播和滥用。因此&#xff0c;保护自己制作的视频非常重要。 那怎样才能够防止别人盗用自己制作的视频呢&#xff1f;一种简单易行的保护方法是…

printContent 点击打印多页时第一页之前出现白页

项目场景&#xff1a; 提示&#xff1a;这里简述项目相关背景&#xff1a; printContent 点击打印多页时第一页之前出现白页 问题描述 提示&#xff1a;这里描述项目中遇到的问题&#xff1a; printContent 点击打印多页时第一页之前出现白页 原因分析&#xff1a; 提示&am…

【中阳期货】分析市场数据和制定交易策略代码

当谈到期货与市场分析时&#xff0c;编写代码来分析市场数据和制定交易策略是一种常见的做法。在这篇文章中&#xff0c;我将向您展示如何使用Python编写代码来获取市场数据、进行基本分析以及制定简单的交易策略。我们将使用一些常见的Python库&#xff0c;如Pandas、Matplotl…

前有CAP理论,后有BASE理论,分布式系统理论基石

&#x1f9d1;‍&#x1f4bb;作者名称&#xff1a;DaenCode &#x1f3a4;作者简介&#xff1a;CSDN实力新星&#xff0c;后端开发两年经验&#xff0c;曾担任甲方技术代表&#xff0c;业余独自创办智源恩创网络科技工作室。会点点Java相关技术栈、帆软报表、低代码平台快速开…

物联网如何改变智能家居技术?

物联网&#xff08;IoT&#xff09;已经在智能家居技术方面产生了深远的影响&#xff0c;其通过将各种设备、传感器和家居设备连接到互联网&#xff0c;实现了智能家居技术的创新和改进。 物联网(IoT)已经在智能家居技术方面产生了深远的影响&#xff0c;其通过将各种设备、传…

【手动实现nn.Linear 】

线性变换参数可视化图 class LinearLayer(nn.Module):def __init__(self, input_dim, output_dim):super(LinearLayer, self).__init__()self.weights nn.Parameter(torch.Tensor(output_dim, input_dim))self.bias nn.Parameter(torch.Tensor(output_dim))# 初始化权重和偏…

codesys自由编码器

1用于位置处理。 2它有个变量&#xff1a; SMC_FreeEncoder.diEncoderPosition 【DINT】 SMC_FreeEncoder_1.diEncoderPosition : GVL.电位器1; SMC_FreeEncoder.diEncoderPosition:hsi_cnt.diCurCountValue; //编码器位置 默认一圈是360.00 给它赋值&#x…

【AI画图】Stable Diffusion WebUI

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kuan 的首页,持续学…

机器学习西瓜书+南瓜书吃瓜教程学习笔记第三章(二)

南瓜书视频链接 以下是我的学习笔记 1、多元线性回归 首先跟着视频推了一遍&#xff0c;真的厉害&#xff0c;很清晰怎么来的 多元线性回归与一元线性回归同理利用最小二乘法求w和b。 这里我们讨论了如何使用线性模型进行回归学习&#xff0c;但若要做的是分类任务呢&#…

dhclient命令 – 动态获取或释放IP地址

参考链接&#xff1a;https://www.linuxcool.com/dhclient # dhclient命令 – 动态获取或释放IP地址 原文链接&#xff1a;https://www.linuxcool.com/dhclient

【计算机操作系统慕课版】第一章课后习题

课后习题目录&#xff1a; 一、简答题 1.在计算机系统上配置OS的目标是什么&#xff1f;作用表现在哪几个方面&#xff1f; 2.试说明OS与硬件、其他系统软件以及用户之间的关系。 3.试说明推动OS发展的主要动力是什么。 4.在OS中&#xff0c;何谓脱机I/O方式和联机I/O方式…

CVE-2023-42442:JumpServer堡垒机会话回放未授权访问漏洞复现

JumpServer堡垒机会话回放未授权访问漏洞&#xff08;CVE-2023-42442&#xff09; 0x01 前言 免责声明&#xff1a;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人…

【系统架构】软件可靠性基础知识

导读&#xff1a;本文整理关于软件可靠性基础知识构建系统架构知识体系。完整和扎实的系统架构知识体系是作为架构设计的理论支撑&#xff0c;基于大量项目实践经验基础上&#xff0c;不断加深理论体系的理解&#xff0c;从而能够创造新解决系统相关问题。 目录 1、软件可靠性…

解决VSCODE 终端中显示中文乱码的问题

这里默认是UTF8 修改为GBK 选择通过编码保存 搜索GBK并选择即可 正常显示