数据结构与算法02 - 复杂度

news2024/9/20 20:26:49

1、空间复杂度

  • 空间复杂度指的是临时占用存储空间大小的量度;
  • 空间复杂度计算的是变量的个数,也采用大O渐进表示法;
  • 由于函数在运行的时候所需要的栈空间(存储参数、局部变量、一些寄存器信息等)在编译器已经确定好了,因此空间复杂度主要通过函数在运行时候显式申请的额外空间来确定!

示例1:冒泡排序

void BubbleSort(int* a, int n)
{
	assert(a);
	for (size_t end = 0; end > 1; --end)
	{
		int exchange = 0;
		for (size_t i = 0; i < end; ++i)
		{
			if (a[i-1] > a[i])
			{
				Swap(&a[i - 1], &a[i]);
				exchange = 1;
			}
		}
		if (exchange = 0);
		break;
	}
	

}

这里只创建了3个变量,为常数个,因此空间复杂度为O(1)。

示例2:斐波那契数列1

long long* Fibonacci(size_t n)
{
	if (n == 0)
		return Fibonacci;
	long long* fibArray = (long long*)malloc((n + 1) * sizeof(long long));
	fibArray[0] = 0;
	fibArray[1] = 1;
	for (int i = 2; i <= n; ++i)
	{
		fibArray[i] = fibArray[i - 1] + fibArray[i - 2];

	}
	return fibArray;
}

 其空间复杂度为O(n);

示例3:递归

long long Fac(size_t N)
{
	if (0 == N)
		return 1;

	return Fac(N - 1) * N;

}

累计调用Fac从Fac(N) ~ Fac(0)共调用n + 1次(要创建函数栈帧),因此空间复杂度为O(n)

下面F1()和F2()打印的值一样吗?

void F1()
{
    int b = 0;
    printf("%p\n",&b);
}

void F2()
{
    int a = 0;
    printf("%p\n",&a);
}

int main()
{
    F1();
    F2();
    return 0;
}

Vs下打印的结果相同,在同一块区域进行相同的函数栈帧的创建和销毁!

示例4:斐波那契数列2(加法)

long long Fib(size_t N)
{
	if (N < 3)
		return 1;
	return Fib(N - 1) + Fib(N - 2);
}

空间复杂度为:O(N)

原因:递归的过程中空间是不断创造和销毁的过程,调用Fib()时先在一侧调用完后返回,此时空间被销毁,然后再重新创建新的空间的过程!

GTP解释:

  • 1. 递归栈空间

    在递归算法中,空间复杂度通常与递归调用的深度有关。每次进行递归调用时,程序会为当前函数调用分配一个栈帧,栈帧会记录函数调用的参数、返回地址和局部变量等信息。

    对于 Fibonacci 函数:

  • 在最坏的情况下,递归深度会达到 N(例如 Fib(N) 需要调用 Fib(N-1) 和 Fib(N-2),一直递归下去),最深的时候调用栈的深度是 N
  • 2. 空间复杂度的计算
  • 因此,空间复杂度是 O(N),这是因为在递归过程中最深的栈帧深度为 N,而且每个栈帧占用的空间是常量级别的。

时间不可重复利用,空间可以重复利用!

示例5:转轮数组

. - 力扣(LeetCode)

直接旋转暴力求解无法通过!

解法一:

解决代码:

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) {
    if (k > numsSize)
        k = k%numsSize;
    reverse(nums,0,numsSize-1-k);
    reverse(nums,numsSize-k,numsSize-1);
    reverse(nums,0,numsSize-1);

}

把++/--放在前面!

这个代码的时间复杂度为O(N),空间复杂度为O(1)

线上OJ分为两种:

  • IO型:通过scanf输入条件,结果通过printf输出,实现一个完整的程序
  • 接口型:输入条件,参数,结果,返回值返回,实现一个函数,只有部分程序
  • 编译错误指的是语法错误,运行错误不通过可能是由于时间复杂度

 解法二:以空间换时间

创建一块空间,将后k个拷贝到前面去,将前k个拷贝到后面去!(1G大概为10亿字节)

示例代码:

void rotate(int* nums, int numsSize, int k)
 {
    if (k > numsSize)
        k = k%numsSize;
    int* tmp = (int*)malloc(sizeof(int)*numsSize);
    memcpy(tmp,nums + numsSize -k,sizeof(int)*k);
    memcpy(tmp+k,nums,sizeof(int)*(numsSize-k));
    memcpy(nums,tmp,sizeof(int)*numsSize);
}

    free(tmp);
    tmp = NULL;

时间复杂度和空间复杂度都为O(N)!

二、顺序表和链表

1、线性表

线性表是n个具有相同特征的数据元素的有限序列!

常见的线性表有:顺序表、链表、栈、队列、字符串

线性表在逻辑上是线性结构,也就是连续的一条直线,但是物理结构(内存中存储)不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储!

2、顺序表

顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。

顺序表一般分为:静态顺序表和动态顺序表

1、静态顺序表:使用定长数组存储元素;

typedef int SLDataType;
#define N 100000

struct SeqList
{
    SLDateType a[N];
    int size;
}

2、动态顺序表:使用动态开辟的数组存储;

typedef int SLDataType;

typedef struct SeqList
{
    SLDataType* a;
    int size;       //有效数据个数
    int capacity;   //空间容量
}SL;

typeef struct SeqList的意思为:将struct SeqList重命名为SL!

有效数据个数 = 空间容量的时候!进行扩容!

对数据的操作分四种:增删查改

void SeqList(SL s);    // 初始化
void SeqDestory(Sl s);  // 删除

全局变量会自己初始化(不初始化也不会报错);局部变量需要自己进行初始化!

需要注意的是,写顺序表初始化的时候,需要传入的是结构体的地址!这样子才能对传入的结构体进行改变,否则只是对临时拷贝的结构体进行改变。

凡是看到错误:无法解析符号 ---- 只有声明没有定义!

顺序表的销毁:将空间释放,然后将指针置为空,再将有效字节和空间大小设置为0;

free空间的时候只能从该空间的起始位置释放,如果从中间位置或者空指针释放会报错!

尾删的时候不能释放单个空间!(创建的空间只能一起释放!)

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

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

相关文章

BERN2(生物医学领域)命名实体识别与命名规范化工具

BERN2: an advanced neural biomedical named entity recognition and normalization tool 《Bioinformatics》2022 1 摘要 NER和NEN&#xff1a;在生物医学自然语言处理中&#xff0c;NER和NEN是关键任务&#xff0c;它们使得从生物医学文献中自动提取实体&#xff08;如疾病…

modelsim仿真流程

modelsim仿真流程 1、建立工程 project new "../prj" test.mpf2、添加rtl文件 project addfile "../test.v" verilog3、建立仿真库 vlib work4、编译rtl到仿真库中 vlog -sv -sv09compat defineT133 incdir"../rtl" test.v -work work5、加载…

【Python】6.基础语法(6)文件

文章目录 1. 文件是什么2. 文件路径3. 文件操作3.1 打开文件3.2 关闭文件3.3 写文件3.4 读文件 4. 关于中文的处理5. 使用上下文管理器 1. 文件是什么 变量是把数据保存到内存中。如果程序重启/主机重启, 内存中的数据就会丢失。 要想能让数据被持久化存储, 就可以把数据存储…

openGauss 之索引回表

一. 前言 ​ 在openGauss中如果表有索引信息&#xff0c;查询的谓词条件中又包含索引列&#xff0c;openGauss支持通过索引信息快速拿到需要访问元组的位置信息&#xff0c;然后直接到该位置上取出元组数据&#xff0c;称之为回表查询。如下所示&#xff0c;利用索引索引…

JS中this指向问题

首先&#xff0c;this的绑定和定义的位置无关&#xff0c;它的指向只和调用方式有关&#xff0c;this只有在运行时才知道指向谁。 一&#xff0c;默认绑定 默认绑定&#xff0c;也可以说是独立函数调用&#xff0c;这时this指向window。 function foo() {console.log(this) …

DataGrip数据迁移

第一步 第二步 第三步 第四步 选择你刚刚到处的文件即可

海信发布以旧换新举措,补贴力度、补贴链路、服务体验全面升级

9月7日&#xff0c;由中国家用电器商业协会主办的“海信全国十城联动以旧换新”发布会在北京举行。 据「TMT星球」了解&#xff0c;活动以“品质换新就选海信”为主题&#xff0c;旨在贯彻政府加大消费品以旧换新的战略部署&#xff0c;为我国家电行业绿色化、智能化、高端化高…

知名AIGC人工智能专家培训讲师唐兴通谈AI大模型数字化转型数字新媒体营销与数字化销售

在过去的二十年里&#xff0c;中国企业在数字营销领域经历了一场惊心动魄的变革。从最初的懵懂无知到如今的游刃有余&#xff0c;这一路走来&#xff0c;既有模仿学习的艰辛&#xff0c;也有创新突破的喜悦。然而&#xff0c;站在人工智能时代的门槛上&#xff0c;我们不禁要问…

最厉害顶尖新媒体营销专家培训讲师唐兴通谈数字营销社群营销私域运营大客户销售AIGC大模型创新思维数字化转型商业模式短视频内容社私域数字经济人工智能

​数字人工智能时代的营销进化&#xff1a;从临摹到自我革新 引言&#xff1a;从模仿到变革的时代拐点 中国企业在过去的几十年里&#xff0c;经历了从电子商务的初兴到搜索引擎营销&#xff0c;再到微博、微信以及短视频等多种数字营销形式的迅速发展。在这个过程中&#xf…

力扣最热一百题——最大子数组和

目录 题目链接&#xff1a;53. 最大子数组和 - 力扣&#xff08;LeetCode&#xff09; 题目描述 示例 提示&#xff1a; 解法一&#xff1a;动态规划 举例分析 时间复杂度 Java写法&#xff1a; C写法&#xff1a; 优化 总结 题目链接&#xff1a;53. 最大子数组和 …

「数学::质数」试除法 / Luogu P5736(C++)

概述 在质数的第一节我们来讲解试除法。 质数是指在大于1的自然数中只能被1和它自己整除的数。 我们可以利用这一除法性质对质数进行判定。 Luogu P5736&#xff1a; 输入 n 个不大于 10^5 的正整数。要求全部储存在数组中&#xff0c;去除掉不是质数的数字&#xff0c;依…

012.Oracle-索引

我 的 个 人 主 页&#xff1a;&#x1f449;&#x1f449; 失心疯的个人主页 &#x1f448;&#x1f448; 入 门 教 程 推 荐 &#xff1a;&#x1f449;&#x1f449; Python零基础入门教程合集 &#x1f448;&#x1f448; 虚 拟 环 境 搭 建 &#xff1a;&#x1f449;&…

828华为云征文|华为云Flexus X实例docker部署rancher并构建k8s集群

828华为云征文&#xff5c;华为云Flexus X实例docker部署rancher并构建k8s集群 华为云最近正在举办828 B2B企业节&#xff0c;Flexus X实例的促销力度非常大&#xff0c;特别适合那些对算力性能有高要求的小伙伴。如果你有自建MySQL、Redis、Nginx等服务的需求&#xff0c;一定…

Differential Diffusion,赋予每个像素它应有的力量,以及在comfyui中的测试效果

&#x1f97d;原论文要点 首先是原论文地址&#xff1a;https://differential-diffusion.github.io/paper.pdf 其次是git介绍地址&#xff1a;GitHub - exx8/differential-diffusion 感兴趣的朋友们可以自行阅读。 首先&#xff0c;论文开篇就给了一个例子&#xff1a; 我们的方…

SpringBoot2:请求处理原理分析-RESTFUL风格接口

一、RESTFUL简介 Rest风格支持&#xff08;使用HTTP请求方式&#xff0c;动词来表示对资源的操作&#xff09; 以前&#xff1a;/getUser 获取用户 /deleteUser 删除用户 /editUser 修改用户 /saveUser 保存用户 现在&#xff1a; /user GET-获取用户 DELETE-删除用户 PUT-修改…

自定义TextView实现结尾加载动画

最近做项目&#xff0c;仿豆包和机器人对话的时候&#xff0c;机器人返回数据是流式返回的&#xff0c;需要在文本结尾添加加载动画&#xff0c;于是自己实现了自定义TextView控件。 源码如下&#xff1a; import android.content.Context import android.graphics.Canvas imp…

Java小程序案例:电子日历记事本

要点 菜单栏中提供编辑&#xff08;剪切、复制、粘贴&#xff09;、保存、打开等功能。使用类组件实现图形界面设计。基于图形界面的日历&#xff0c;用户可编辑或查看指定日期的日志内容。提供按钮实现月份的前后翻动。事件持久化到文件&#xff0c;可再次编辑保存 效果 程序…

【工具】使用 Jackson 实现优雅的 JSON 格式化输出

说明 在 Java 开发中&#xff0c;我们经常需要处理 JSON 数据。无论是从服务器端返回的数据&#xff0c;还是本地存储的数据&#xff0c;JSON 格式都因其轻量级和易于解析的特点而被广泛使用。当我们需要查看或调试 JSON 数据时&#xff0c;优雅、格式化的输出将大大提高我们的…

风控系统之指标回溯,历史数据重跑

个人博客&#xff1a;无奈何杨&#xff08;wnhyang&#xff09; 个人语雀&#xff1a;wnhyang 共享语雀&#xff1a;在线知识共享 Github&#xff1a;wnhyang - Overview 回顾 默认你已经看过之前那篇风控系统指标计算/特征提取分析与实现01&#xff0c;Redis、Zset、模版方…

C++万字解读类和对象(上)

1.类的定义 class为定义类的关键字&#xff0c;Stack为类的名字&#xff0c;{}中为类的主体&#xff0c;注意类定义结束时后面分号不能省略。类体中内容称为类的成员&#xff1a;类中的变量称为类的属性或成员变量; 类中的函数称为类的方法或者成员函数。 为了区分成员变量&…