数据结构之复杂度

数据结构的理解

数据本身是杂乱无章的,需要结构进行增删查改等操作更好的管理数据;

比如:在程序中需要将大量的代码(数据)通过结构进行管理;
再比如:定义1000个整型变量的数组,我们可以对数组进行删除某一个数据,在某一个数据后面插入新的数据等等操作。这些都是数据结构的体现。

数据结构是用来在计算机中存储和管理数据的,这种存储和管理的方式有很多种,我们后面会一一学到比如:线性表、数、图、哈希等

数组是最基础的数据结构;

算法理解

算法是一个良好计算的过程,我们可以将数据结构作为放着数据的容器,而算法就是用来如何才能让我们良好的从容器中获取和管理数据的这么一个过程就叫做算法

因此:有数据结构的地方就有算法,数据结构和算法不分家

算法重要性

在笔试和面试中是必考的,是以编程题的形式进行考察,我们要好好磨砺算法,做到手撕代码 <:

学好算法秘籍:

1.死磕代码
2.遇到算法题莫慌,带着思考进行画图。
3.看关于算法和数据结构的书藉
4.使用各大OJ平台进行刷题(用OJ平台刷题的魅力:只需要写入内部的逻辑代码即可,其他的平台都已经定义好了)

自己下去将轮转数组进行单独实现
如何衡量算法的好坏呢? ----->用复杂度进行衡量

复杂度理解

而复杂度又包含时间复杂度和空间复杂度
时间复杂度主要衡量一个算法的运行快慢;
空间复杂度主要衡量一个算法运行所需要的额外空间
随着时代的发展,我们对空间的关注已经不是大头了,时间才是,注意不是不关注!(也就是摩尔定律)

时间复杂度理解

时间复杂度是一个函数表达式T(N),这个与数学中的定义的一次函数和二次函数是一样的,它是用来衡量程序的运行效率。它是一个粗估的值,不是精确的值。
为什么不去计算程序的运行时间呢?

1.因为程序的运行时间和编译环境和运行机器的配置都有关系,
比如:同一个算法程序,用一个老的编译器进行编译和新的编译器编译,在同样的运行机器下程序运行时间不同
2.同一个算法程序,在不同的运行机器下(在一个老低配置机器和新高配置机器的情况下)使用同一个编译器进行编译,程序运行时间也会不一样
3. 并且计算程序的运行时间只能在程序运行之后才能知道,不能在写程序之前就知道大概的运行时间是多少。

总结:程序的运行时间是不确定的

时间复杂度T(N)到底怎么去计算呢?
T(N) = 每条语句的运行时间 * 运行次数
前面我们知道运行时间是不确定的,所以将运行时间去掉,所以
T(N) = 程序的运行次数

在这里插入图片描述

这个程序的时间复杂度T(N) = N^2 + 2N + 10
因为2N + 10 对时间复杂度的影响很小,所以忽略不计,最终:T(N) = N^2

因此,对于时间复杂度来说,是一个粗估的值,争对这种情况,我们有了大O的渐进表示法的计算法则进行计算

大O的渐进表示法

大O的计算规则:

  1. 时间复杂度T(N) 中,只保留最高项,去掉最低项,包括常数项
  2. 如果最高项的常数系数存在且不是1,则去除这个项目的常数系数
  3. 如果T(N) 中只有常数项,用常数1代表所有的加法常数。 O(1)来表示

判断高阶项的方法:对结果影响最大就是高阶项

大O的渐进表示法在空间和时间上都可以用
时间复杂度举例:

以下是常见时间复杂度的计算:

在这里插入图片描述
T(N) = 2N + 10 根据法则2:O(N)
在这里插入图片描述
如果T(N) 中存在两个变量,不确定这两个变量的大小,则这两个变量都可以表示,例如:O(M + N), M 和 N 都是变量,具体看题目中是如何定义M和N 的大小,比如:M >> N, 则为O(M),反之则为O(N);在有一种情况就是M == N, 则为O(M+N)。
在这里插入图片描述
T(N) = 100, 根据法则3:O(1)

请写出查找字符长度的时间复杂度
在这里插入图片描述

这里T(N) 的大小取决于你所要查找的位置,
比如:
查找的字符的位置在最后一个位置,则为O(N)
查找的字符的位置在第一个位置,则为O(1)
查找的字符的位置在中间位置,则为O(1/2 * N) = O(N)

最好情况: O(1)
最坏情况: O(N)
平均情况: O(N)

总结 通过上面我们会发现,有些算法的时间复杂度存在最好、平均和最坏情况。 最坏情况:任意输入规模的最大运行次数(上界)
平均情况:任意输入规模的期望运行次数 最好情况:任意输入规模的最小运行次数(下界)
大O的渐进表示法在实际中一般情况关注的是算法的上界,也就是最坏运行情况。

在看看冒泡排序的时间复杂度:
在这里插入图片描述
因此,我们取得是上界的情况:O(N^2)

再看看这道题
在这里插入图片描述

这里需要注意的是:
课件中和书籍中 log2 n 、 log n 、 lg n 的表示
当n接近⽆穷⼤时,底数的⼤⼩对结果影响不⼤。因此,⼀般情况下不管底数是多少都可以省略不 写,即可以表⽰为 log n
不同书籍的表⽰⽅式不同,以上写法差别不⼤,我们建议使⽤ log n
还有一个原因是:键盘中敲不出底数

在这里插入图片描述

到这里时间复杂度的计算就够够用了

空间复杂度

空间复杂度计算规则基本跟时间复杂度类似,也使⽤⼤O渐进表⽰法。
注意:我们计算空间复杂度时只计算函数运⾏时所需要的栈空间,存储参数、局部变量、⼀些寄存器信息和非递归函数调用的栈帧等都是在函数运行时的内容。
因此空间复杂度主要通过函数在运⾏时候显式申请的额外空间来确定,也就是函数定义的下面那一部分

以下是常见的空间复杂度的计算:
在这里插入图片描述
在这里插入图片描述

常见的空间复杂度计算

通过动态内存申请内容也会涉及到空间复杂度的计算
例如:
在这里插入图片描述

常⻅复杂度对⽐:

在这里插入图片描述
在这里插入图片描述
总结:随着n的增加,各种的复杂度的变化趋势也大不相同;随着n的增加,变化越缓的复杂度代表着在程序运行时的效率高;越陡的效率低

关于复杂度的相关算法题:

轮转数组

思路1:

	时间复杂度 O(n^2)循环K次将数组所有元素向后移动⼀位(代码不通过)

在这里插入图片描述

核心代码如下:

void rotate(int* nums, int numsSize, int k) {while(k--)//直到轮转结束后就停止{int end = nums[numsSize-1];for(int i = numsSize - 1; i > 0; i--)//这里是整体向后移的操作,起始位置在最后一位,直到将第一个数据移到第二位后就结束{nums[i] = nums[i - 1];//将一位的数据移到后一位}nums[0] = end;//将最后的移到第一位}
}

在这里插入图片描述

思路2:

空间复杂度 O(n)
申请新数组空间,先将后k个数据放到新数组中,再将剩下的数据挪到新数组中
在这里插入图片描述

核心代码:

void rotate(int* nums, int numsSize, int k) {int NewArr[numsSize];for(int i = 0; i < numsSize; i++){NewArr[(k + i) % numsSize] = nums[i];//这里是将原数组中的数据放入到新数组下标为(k + i) % numsSize中}for(int i = 0; i < numsSize; i++){nums[i] = NewArr[i]; //再放到原数组中去}}

思路3:

逆置:是指将开始的位置(begin) 和末尾的位置(last)相互置换,多次置换时需要begin++,last–。

空间复杂度 O(1)
先将前n-k个逆置:5 6 7
再将后k个逆置 :4 3 2 1
最后将整体逆置 :5 6 7 1 2 3 4

核心代码:

//逆置的过程可以分装成一个函数
void reverse(int* nums, int begin, int end)
{while(begin < end) {int tmp = nums[begin];nums[begin] = nums[end];nums[end] = tmp;begin++;end--;}   }void rotate(int* nums, int numsSize, int k) {k = k % numsSize;//先将前n-k个进行逆置reverse(nums, 0, numsSize - 1 - k);//这里传的是数组的下标//再将后k个进行逆置reverse(nums, numsSize - k, numsSize - 1);//最后整体进行逆置reverse(nums, 0, numsSize - 1);
}

假设数组的个数非常大,有n个,我们从头 和 尾 两两逆置,总共逆置了1/2 * n次,所以时间复杂度为O(N), 我们也没有额外申请空间,所以空间复杂度为O(1)

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

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

相关文章

运维安全06 - 服务安全

云计算服务安全 在当今数字化时代&#xff0c;各种服务&#xff08;如网络应用、云计算平台、数据库系统等&#xff09;已成为我们日常生活和工作中不可或缺的一部分。 然而&#xff0c;随着服务的广泛应用&#xff0c;其安全性问题也日益凸显。 一、服务安全 服务安全是一…

01数据结构-初探动态规划

01数据结构-初探动态规划前言1.基本思想2.重叠子问题3.斐波那契数列4.备忘录&#xff08;记忆化搜索表&#xff09;4.1备忘录&#xff08;记忆化搜索表&#xff09;代码实现5.DP table5.1DP table代码实现6.练习前言 在学习动态规划时切忌望文生义&#xff0c;因为其名字与其思…

[智能算法]可微的神经网络搜索算法-FBNet

一、概述 相较于基于强化学习的NAS&#xff0c;可微NAS能直接使用梯度下降更新模型结构超参数&#xff0c;其中较为有名的算法就是DARTS&#xff0c;其具体做法如下。 首先&#xff0c;用户需要定义一些候选模块&#xff0c;这些模块内部结构可以互不相同&#xff08;如设置不同…

Elasticsearch安装启动常见问题全解析

文章目录&#x1f4da; Elasticsearch 安装与启动问题总结一、核心问题概览二、详细问题分析与解决方案1. &#x1f510; **权限问题&#xff1a;AccessDeniedException**❌ 错误日志&#xff1a;&#x1f4cc; 原因&#xff1a;✅ 解决方案&#xff1a;2. ⚙️ **配置冲突&…

Uniapp中使用renderjs实现OpenLayers+天地图的展示与操作

Uniapp中自带的地图组件对支持的地图服务略有局限&#xff0c;同时&#xff0c;该组件在样式布局上层级过高且无法控制&#xff0c;无法满足部分高度自定义化的需求。故引入renderjs视图层工具搭配OpenLayers框架对地图功能进行实现&#xff0c;但由于renderjs的限制&#xff0…

从C++开始的编程生活(8)——内部类、匿名对象、对象拷贝时的编译器优化和内存管理

前言 本系列文章承接C语言的学习&#xff0c;需要有C语言的基础才能学会哦~ 第8篇主要讲的是有关于C的内部类、匿名对象、对象拷贝时的编译器优化和内存管理。 C才起步&#xff0c;都很简单&#xff01;&#xff01; 目录 前言 内部类 性质 匿名对象 性质 ※对象拷贝时的…

MT5追大速率回测BUG

将MT5策略测试器中的回测速率调到最大(最快速度),**确实非常容易导致出现不符合策略逻辑的秒级成交(闪电交易)**。这并非MT5的“bug”,而是由**回测引擎的工作方式**与**策略代码的编写方法**在高速运行下不匹配所导致的。 --- ### 为什么最大速率会导致问题? MT5回测…

[数据结构——lesson10.堆及堆的调整算法]

引言 上节我们学习完二叉树后[数据结构——lesson9.二叉树]&#xff0c;这节我们将学习数据结构——堆 学习目标 1.堆的概念及结构 堆是一种特殊的完全二叉树结构&#xff0c;在计算机科学和数据结构中广泛应用&#xff0c;特别是在堆排序算法和优先队列的实现中&#xff0c;…

九识智能与北控北斗合作研发的L4级燃气超微量高精准泄漏检测无人车闪耀服贸会,守护城市安全

2025年9月10日至14日&#xff0c;2025年中国国际服务贸易交易会将于北京首钢园举办。在这场国际盛会上&#xff0c;九识智能与北京北控北斗科技投资有限公司&#xff08;以下简称“北控北斗”&#xff09;合作研发的L4级燃气超微量高精准泄漏检测无人车及相关系统解决方案&…

【C语言入门】手把手教你实现顺序栈

栈是计算机科学中最基础且重要的数据结构之一&#xff0c;它遵循"后进先出"&#xff08;LIFO&#xff09;的原则。想象一下一叠盘子&#xff0c;你只能从最上面取放&#xff0c;这就是栈的直观体现。本文将用C语言带你一步步实现一个顺序栈&#xff0c;即使你是编程小…

北斗导航 | ARAIM(高级接收机自主完好性监测)算法在民航LPV-200进近中的具体实现流程

要详细说明ARAIM(高级接收机自主完好性监测)算法在民航LPV-200进近中的具体实现流程,需结合ARAIM的核心逻辑(多星座融合、多假设解分离、风险优化分配)与LPV-200的严格要求(垂直保护级VPL≤35米、垂直告警限VAL=35米、有效监测门限EMT≤15米等),以下是 step-by-step 的…

AIPex:AI + 自然语言驱动的浏览器自动化扩展

AIPex:AI + 自然语言驱动的浏览器自动化扩展 引言 一、快速上手 1.1 安装AIPex扩展 1.2 首次配置 1.3 界面介绍 第二章:30+工具详解 2.1 标签页管理工具集 🗂️ **get_all_tabs - 全局标签页概览** 🎯 **switch_to_tab - 智能标签页切换** 📋 **标签页批量操作** 📋 …

机器学习模型可信度与交叉验证:通俗讲解

先从一个故事说起&#xff1a;农场里的火鸡科学家&#xff0c;观察了一年发现“每天上午11点必有食物”&#xff0c;结果感恩节当天&#xff0c;它没等到食物&#xff0c;反而成了人类的食物。这个故事告诉我们&#xff1a;只靠过去的经验下结论&#xff0c;很可能出错——机器…

HTML5和CSS3新增的一些属性

1、HTML5新增特性这些新特性都有兼容性问题&#xff0c;基本是IE9以上版本浏览器才支持1&#xff09;新增语义化标签2&#xff09;新增多媒体标签音频&#xff1a;<audio>视频&#xff1a;<video>&#xff08;1&#xff09;视频<video>---尽量使用mp4格式<…

Redis的RedLock

RedLock算法深度解析RedLock是Redis作者针对分布式环境设计的多节点锁算法&#xff0c;核心目标是解决单点Redis在分布式锁场景中的可靠性缺陷。传统方案的局限性单节点Redis锁的问题单点故障&#xff1a;单个Redis实例宕机导致所有锁服务不可用可靠性不足&#xff1a;无法保证…

SpringMVC @RequestMapping的使用演示和细节 详解

目录 一、RequestMapping是什么&#xff1f; 二、RequestMapping 的使用演示 1.RequestMapping在方法上的使用&#xff1a; 2.RequestMapping同时在类和方法上使用&#xff1a; 3.RequestMapping指定请求参数&#xff1a; 4.RequestMapping使用Ant风格URL&#xff1a; 5.Requ…

flutter项目 -- 换logo、名称 、签名、打包

1、换logo, 透明底&#xff0c;下面5个尺寸&#xff0c;需要UI设计2、换名没配置型的改名方式如下 打开app/src/main/AndroidManifest.xml3、签名 运行 flutter doctor -vD:\project\Apk\keystore 自己建立的keystore文件夹&#xff0c; 注意命令后是 megoai-release-key(自…

【贪心算法】day9

&#x1f4dd;前言说明&#xff1a; 本专栏主要记录本人的贪心算法学习以及LeetCode刷题记录&#xff0c;按专题划分每题主要记录&#xff1a;&#xff08;1&#xff09;本人解法 本人屎山代码&#xff1b;&#xff08;2&#xff09;优质解法 优质代码&#xff1b;&#xff…

linux C 语言开发 (八) 进程基础

文章的目的为了记录使用C语言进行linux 开发学习的经历。开发流程和要点有些记忆模糊&#xff0c;赶紧记录&#xff0c;防止忘记。 相关链接&#xff1a; linux C 语言开发 (一) Window下用gcc编译和gdb调试 linux C 语言开发 (二) VsCode远程开发 linux linux C 语言开发 (…

从零学算法1094

1094.拼车 车上最初有 capacity 个空座位。车 只能 向一个方向行驶&#xff08;也就是说&#xff0c;不允许掉头或改变方向&#xff09; 给定整数 capacity 和一个数组 trips , trips[i] [numPassengersi, fromi, toi] 表示第 i 次旅行有 numPassengersi 乘客&#xff0c;接他…