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

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 100000struct 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.mzph.cn/bicheng/53496.shtml

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

相关文章

Kafka【十二】消费者拉取主题分区的分配策略

【1】消费者组、leader和follower 消费者想要拉取主题分区的数据&#xff0c;首先必须要加入到一个组中。 但是一个组中有多个消费者的话&#xff0c;那么每一个消费者该如何消费呢&#xff0c;是不是像图中一样的消费策略呢&#xff1f;如果是的话&#xff0c;那假设消费者组…

MySQL 锁分类有哪些?一文带你详解!!

MySQL 锁 全局锁全局锁的应用场景全局锁的缺点 表级锁表锁元数据&#xff08;MDL&#xff09;锁MDL 锁的问题 意向锁AUTO-INC 锁 行级锁记录锁&#xff08;Record Lock&#xff09;间隙锁&#xff08;Gap Lock&#xff09;临键锁&#xff08;Next-Key Lock&#xff09;插入意向…

Opencv中的直方图(2)计算图像的直方图函数calcHist()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 计算一组数组的直方图。 函数 cv::calcHist 计算一个或多个数组的直方图。用于递增直方图bin的元组的元素是从相同位置的相应输入数组中获取的。…

Cursor是什么?Cursor Pro Plus 如何订阅升级教程

一、Cursor是什么&#xff1f; Cursor 是一个基于 Visual Studio Code&#xff08;VS Code&#xff09;技术构建的高级代码编辑器&#xff0c;专为提高编程效率并更深度地整合 AI 功能而设计。它不仅继承了 VS Code 的强大功能和用户界面&#xff0c;还增加了专门针对 AI 支持…

Agent(智能体)和 MetaGPT,一句话实现整个需求应用代码

前面 2 篇文章&#xff0c;我们使用文生文、文生图和文生音频三个大模型共同实现了图文并茂的儿童绘本故事和绘本故事音频需求&#xff1a; 第一篇 根据主题生成儿童绘本故事&#xff1a;GLM-4-Flash 大模型 API 免费了&#xff0c;手把手构建“儿童绘本”应用实战&#xff08…

Nuxt3入门:过渡效果(第5节)

你好同学&#xff0c;我是沐爸&#xff0c;欢迎点赞、收藏、评论和关注。 Nuxt 利用 Vue 的 <Transition> 组件在页面和布局之间应用过渡效果。 一、页面过渡效果 你可以启用页面过渡效果&#xff0c;以便对所有页面应用自动过渡效果。 nuxt.config.js export defaul…

概率DP (由一道绿题引起的若干问题。目前为一些老题,蒟蒻的尝试学习1.0)

概率DP&#xff1a; 利用动态规划去解决 概率 期望 的题目。 概率DP 求概率&#xff08;采用顺推&#xff09; 从 初始状态推向结果&#xff0c;同一般的DP类似&#xff0c;只是经历了概率论知识的包装。 老题&#xff1a; 添加链接描述 题意&#xff1a; 袋子里有w只白鼠&am…

linux编译器——gcc/g++

1.gcc linux上先要安装&#xff0c; sudo yum install gcc gcc --version 可以查看当前的版本 &#xff0c;我们默认安装的是4.8.5的版本&#xff0c;比较低&#xff0c; gcc test.c -stdc99 可以使他支持更高版本的c标准 -o 可以殖指明生成文件的名字&#xff0c;可以自己…

跨越技术壁垒:EasyCVR为何选择支持FMP4格式,重塑视频汇聚平台标准

随着物联网、大数据、云计算等技术的飞速发展&#xff0c;视频监控系统已经从传统的安防监控扩展到智慧城市、智能交通、工业制造等多个领域。视频流格式作为视频数据传输与存储的基础&#xff0c;其兼容性与效率直接影响到整个视频监控系统的性能。 在众多视频流格式中&#…

TCP Analysis Flags 之 TCP Port numbers reused

前言 默认情况下&#xff0c;Wireshark 的 TCP 解析器会跟踪每个 TCP 会话的状态&#xff0c;并在检测到问题或潜在问题时提供额外的信息。在第一次打开捕获文件时&#xff0c;会对每个 TCP 数据包进行一次分析&#xff0c;数据包按照它们在数据包列表中出现的顺序进行处理。可…

十大口碑最好开放式蓝牙耳机是哪些?五款热销好用产品测评!

​开放式耳机现在超火&#xff0c;成了时尚、好看又舒服的代名词&#xff0c;迅速俘获了一大波粉丝&#xff0c;成了耳机界的新宠儿。跟那些传统的入耳式耳机比起来&#xff0c;开放式耳机戴着更稳&#xff0c;对耳朵也更友好。不过&#xff0c;也有人觉得这玩意儿不值&#xf…

系统找不到指定的文件怎么解决?

把U盘插在电脑上&#xff0c;当我打开U盘中的文件时&#xff0c;弹窗提示系统找不到指定的文件&#xff0c;这是什么情况&#xff1f;有谁遇到过吗&#xff1f;大家有没有解决办法&#xff1f; 这个问题可能大家并不陌生&#xff0c;可能也曾遇到过&#xff0c;造成问题出现的原…

现代计算机中数字的表示与浮点数、定点数

现代计算机中数字的表示与浮点数、定点数 导读&#xff1a;浮点数运算是一个非常有技术含量的话题&#xff0c;不太容易掌握。许多程序员都不清楚使用操作符比较float/double类型的话到底出现什么问题。这篇文章讲述了浮点数的来龙去脉&#xff0c;所有的软件开发人员都应该读…

sqli-lab靶场学习(一)——Less1-4

前言 最近一段时间想切入安全领域&#xff0c;因为本身有做数据库运维工作&#xff0c;就打算从sql注入方向切入。而sql注入除了学习日常书本上的概念外&#xff0c;需要有个实践的环境&#xff0c;刚好看到sqli-lab这个靶场&#xff0c;就打算先用这个来学习。 安装部署 网上…

小阿轩yx-Kubernertes日志收集

小阿轩yx-Kubernertes日志收集 前言 在 Kubernetes 集群中如何通过不同的技术栈收集容器的日志&#xff0c;包括程序直接输出到控制台日志、自定义文件日志等 有哪些日志需要收集 日志收集与分析很重要&#xff0c;为了更加方便的处理异常 简单总结一些比较重要的需要收集…

数据分析面试题:如何分析每日平均每件商品的锁定时长问题?

目录 0 题目描述 2 数据准备 3 数据分析 3.1 需求1:计算 2014/03/22-2014/04/30 每天的购买客户数、订单量、销售件数、销售额 3.2 计算 2014 年 4 月各品类的销售额、晚上 20-24 点销售额 3.3 提取 2014 年 3-5 月销售额排名前三的客户信息(排名/客户号/客户姓名/总销…

华为OD机试真题 - 二叉树的广度优先遍历 - 二叉树(Python/JS/C/C++ 2024 D卷 200分)

华为OD机试 2024E卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试真题&#xff08;Python/JS/C/C&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;私信哪吒&#xff0c;备注华为OD&#xff0c;加入华为OD刷题交流群&#xff0c;…

Github 2024-09-07Rust开源项目日报Top10

根据Github Trendings的统计,今日(2024-09-07统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Rust项目10CUE项目1Python项目1Go项目1Polars: Rust中的DataFrame接口和OLAP查询引擎 创建周期:1354 天开发语言:Rust, Python协议类型:MIT …

Ubuntu之源码编译安装nginx

参考&#xff1a;Ubuntu之源码编译安装nginx_ubuntu编译安装nginx-CSDN博客 1.下载源码后进入源码目录&#xff0c;如下&#xff1a; cd /home/jq/wf/nginx-1.26.1 2.下载相应依赖库&#xff1a; apt-get install libpcre3-dev apt-get install openssl libssl-dev apt-get…

神经网络骨架nn.Module

文章目录 一、认识nn.Module二、nn.Module的基础加1操作 一、认识nn.Module nn.Module 是 PyTorch 中的一个核心类&#xff0c;它是所有神经网络模块的基类。在 PyTorch 中构建模型时&#xff0c;通常会继承这个类来创建自定义的网络结构。nn.Module 提供了一系列用于构建神经…