当前位置: 首页 > news >正文

数据结构刷题

空间复杂度:临时开辟的空间、空间是可以重复利用的

递归为O(n)

时间复杂度:程序执行次数

消失的数字

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

思路1:利用连续的特点求等差和然后减去所有元素得到的就是消失的数字

时间复杂度:O(n)     空间复杂度:O(1)

思路2:将给定数组的元素和连续的元素进行异或(异或与顺序无关),相同元素异或结果为0。会得到有一个落单的数字与0异或就是这个数字。

时间复杂度:O(n)     空间复杂度:O(1)

第一种方法大家自行实现,我们可以实现一下不常见的第二种方法:

int missingNumber(int* nums, int numsSize){int x = 0;//0与任何数异或为该数for(int i = 0;i<numsSize;i++){x ^= nums[i];}for(int i = 0;i<=numsSize;i++){x ^= i;}return x;
}

轮转数组

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

c语言阶段曾实现了两种方法,一种是依次移动,移动M次。一种是局部逆置和整体逆置。前者时间复杂度为O(N*M),后者为O(N)

空间换时间:创建一个临时数组,前面放需要旋转的数据,后面放没有旋转的数据即可。 

不完整代码: 

void rotate(int* nums, int numsSize, int k){int tmp[numsSize];k %= numsSize;//循环次数不必多于元素个数int i = 0;int j = 0;for(i=numsSize-k;i<numsSize;i++){tmp[j] = nums[i];j++;}for(i = 0;i<numsSize-k;i++){tmp[j] = nums[i];
}
for//打印
}

有效的括号

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

思路:让左括号依次入栈,与右括号匹配。

匹配前:判断栈是否为空,为空说明无左括号。返回false。

匹配中:匹配涉及多次如 " () {} (())",记录指针位置与栈顶比较,然后出栈,不匹配返回false。

匹配结束栈空为匹配成功,否则匹配失败。

注意返回前都需进行销毁操作。

#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
typedef char STDatatype;
typedef struct Stack
{STDatatype* a;int capacity;int top;
}ST;
void check_capacity(ST* ps)
{if(ps->capacity == ps->top){int newCapacity = 0 ? 4:ps->capacity*2;char* tmp;tmp = (STDatatype*)realloc(ps->a,sizeof(STDatatype) * newCapacity);if (tmp == NULL){perror("malloc");exit(-1);}ps->a = tmp;ps->capacity = newCapacity;}
}
bool StackEmpty(ST* ps)//判空
{assert(ps);return ps->top == 0;
}
STDatatype StackTop(ST* ps)
{assert(ps);assert(!StackEmpty(ps));return ps->a[ps->top-1];//top为最后一个元素的下一个
}
void StackDestroy(ST* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->top = ps->capacity = 0;
}
void StackInit(ST* ps)
{/*ps->a = NULL;ps->top = 0;ps->capacity = 0;*///初始化空间ps->a = (STDatatype*)malloc(sizeof(STDatatype) * 4);if (ps->a == NULL){perror("malloc");exit(-1);}ps->top = 0;ps->capacity = 4;
}
void StackPop(ST* ps)//出栈
{assert(ps);//if(ps->top>0)assert(!StackEmpty(ps));ps->top--;
}
void StackPush(ST* ps, STDatatype x)
{assert(ps);check_capacity(ps);ps->a[ps->top] = x;ps->top++;//指向下一个
}
bool isValid(char* s) {ST ps;StackInit(&ps); 
while(*s)
{if(*s == '(' || *s == '[' ||*s == '{' ){StackPush(&ps,*s);s++;}else{if(StackEmpty(&ps))//如果没有左括号,栈顶没有元素{StackDestroy(&ps);//注意返回前都要手动释放空间return false;}char top = StackTop(&ps);if((*s == ')' && top != '(') || (*s == ']' && top != '[') ||(*s == '}' && top != '{'))//{StackDestroy(&ps);return false;}else{StackPop(&ps);s++;}}
}
bool ret = StackEmpty(&ps);
StackDestroy(&ps);
return ret;
}

用队列实现栈

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

先导入我们实现过的队列:

#pragma once
#include <stdbool.h>
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
typedef int QDataType;
typedef struct QueueNode
{QDataType data;struct QueueNode* next;
}QNode;
struct Queue
{QNode* head;QNode* tail;int size;
};
void QueueInit(Queue* pq);
void QueueDestroy(Queue* pq);
void QueuePush(Queue* pq, QDataType x);
void QueuePop(Queue* pq);
QDataType QueueFront(Queue* pq);
QDataType QueueBack(Queue* pq);
bool QueueEmpty(Queue* pq);
int QueueSize(Queue* pq);void QueueDestroy(Queue* pq)
{assert(pq);QNode* cur = pq->head;while (cur){QNode* Next =cur->next;free(cur);cur = Next;}pq->head = pq->tail = NULL;//避免野指针pq->size = 0;
}
void QueuePush(Queue* pq, QDataType x)
{assert(pq);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc fail");exit(-1);}   newnode->data = x;newnode->next = NULL;pq->size++;if (pq->head == NULL){pq->head = pq->tail = newnode;}else{pq->tail->next = newnode;pq->tail = newnode;}
}
void QueuePop(Queue* pq)
{//出队头删assert(pq);assert(pq->head);QNode* del = pq->head;pq->head = pq->head->next;free(del);if (pq->head == NULL)pq->tail = NULL;pq->size--;}
void QueueInit(Queue* pq)
{assert(pq);pq->head = NULL;pq->tail = NULL;pq->size = 0;
}
bool QueueEmpty(Queue* pq)
{assert(pq);return pq->head == NULL && pq->tail == NULL;
}
int QueueSize(Queue* pq)
{assert(pq);return pq->size;
}
QDataType QueueFront(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->head->data;
}
QDataType QueueBack(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->tail->data;
}

 两个队列

将两个队列封装在一个结构体中。

typedef struct Queue
{QNode* head;QNode* tail;int size;
}Queue;//简写

创建并初始化链表(栈)

注意要想保证我们创建的结构体生命周期能够贯彻整个工程,必须在上申请空间。

MyStack* myStackCreate() {//创建并初始化链表MyStack* obj = (MyStack*)malloc(sizeof(MyStack));//堆区QueueInit(&obj->q1);QueueInit(&obj->q2);return obj;
}

模拟入栈

选择非空队列插入即可。

void myStackPush(MyStack* obj, int x) {if(!QueueEmpty(&obj->q1))//非空队列插入{QueuePush(&obj->q1,x);}elseQueuePush(&obj->q2,x);
}

模拟出栈

出栈是在队尾进行出(后进先出),我们将非空队列进行出队只剩下最后一个元素即是栈顶的元素,然后将其保存后出栈避免造成内存泄露,然后返回。

nt myStackPop(MyStack* obj) {//假定一方不为空Queue* empty = &obj->q1;Queue* nonempty = &obj->q2;if(!QueueEmpty(empty)){empty = &obj->q2;nonempty = &obj->q1;}while(QueueSize(nonempty) > 1)//O(1)导入空来链表{QueuePush(empty,QueueFront(nonempty));//非空取队头插入空 QueuePop(nonempty);}//保证原链表返回为空int top = QueueFront(nonempty);QueuePop(nonempty);//出栈return top;
}

模拟栈顶

直接返回队尾元素即可。

int myStackTop(MyStack* obj) {//返回队尾if(!QueueEmpty(&obj->q1)){return QueueBack(&obj->q1);}elsereturn QueueBack(&obj->q2);	
}

模拟栈判空

bool myStackEmpty(MyStack* obj) {return QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2);
}

模拟栈销毁

除了释放队列指针组合的结构体外,还要将每个队列里的元素释放。

void myStackFree(MyStack* obj) {QueueDestroy(&obj->q1);QueueDestroy(&obj->q2);free(obj);
}

用栈实现队列

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

思路:两个栈,一个负责push数据,一个负责pop数据,在pop数据时,判断pop栈中是否有数据,没有则将push栈的数据全部导入,此时数据顺序反过来后再pop栈里出栈就可以实现先进先出这一特性了。

导入实现好的栈:


#include <stdbool.h>
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>typedef int STDatatype;
typedef struct Stack
{STDatatype* a;int capacity;int top;
}ST;void StackInit(ST* ps);
void StackDestroy(ST* ps);
void StackPush(ST* ps, STDatatype x);
void StackPop(ST* ps);//出栈
STDatatype StackTop(ST* ps);bool StackEmpty(ST* ps);
int StackSize(ST* ps);void StackInit(ST* ps)
{/*ps->a = NULL;ps->top = 0;ps->capacity = 0;*///初始化空间ps->a = (STDatatype*)malloc(sizeof(STDatatype) * 4);if (ps->a == NULL){perror("malloc");exit(-1);}ps->top = 0;ps->capacity = 4;
}static void check_capacity(ST* ps)
{if (ps->top == ps->capacity){int newCapacity = ps->capacity * 2;STDatatype* tmp = (STDatatype*)realloc(ps->a, newCapacity *sizeof(STDatatype));if (tmp == NULL){perror("realloc");exit(-1);}else{ps->a = tmp;ps->capacity == newCapacity;}}
}
void StackPush(ST* ps, STDatatype x)
{assert(ps);check_capacity(ps);ps->a[ps->top] = x;ps->top++;//指向下一个
}
void StackPop(ST* ps)//出栈
{assert(ps);//if(ps->top>0)assert(!StackEmpty(ps));ps->top--;
}STDatatype StackTop(ST* ps)
{assert(ps);assert(!StackEmpty(ps));return ps->a[ps->top-1];//top为最后一个元素的下一个
}
void StackDestroy(ST* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->top = ps->capacity = 0;
}
bool StackEmpty(ST* ps)//判空
{assert(ps);return ps->top == 0;
}
int StackSize(ST* ps)
{assert(ps);return ps->top;
}

两个栈

typedef struct {ST pushst;//入队ST popst;//出队
} MyQueue;

Create


MyQueue* myQueueCreate() {//初始化+开空间MyQueue* st = (MyQueue*)malloc(sizeof(MyQueue));StackInit(&st->pushst);StackInit(&st->popst);return st;
}

Push

void myQueuePush(MyQueue* obj, int x) {assert(obj);StackPush(&obj->pushst,x);
}

判空 

bool myQueueEmpty(MyQueue* obj) {assert(obj);return StackEmpty(&obj->pushst) && StackEmpty(&obj->popst);
}

查看队头

由于popst的栈顶为队头,如果该栈为,需要导入pushst的数据。

int myQueuePeek(MyQueue* obj) {assert(obj);assert(!myQueueEmpty(obj)); //双栈判空if(StackEmpty(&obj->popst)){while(!StackEmpty(&obj->pushst))//导数据{StackPush(&obj->popst,StackTop(&obj->pushst));StackPop(&obj->pushst);}}return StackTop(&obj->popst);
}

Pop

同样涉及判空和调用队头元素,通过调用peek函数判断并完成对数据的导入并接收其返回值,

int myQueuePop(MyQueue* obj) {int qhead = myQueuePeek(obj);StackPop(&obj->popst);//出队return qhead;
}

释放

void myQueueFree(MyQueue* obj) {assert(obj);StackDestroy(&obj->pushst);StackDestroy(&obj->popst);free(obj);
}

相关文章:

数据结构刷题

空间复杂度&#xff1a;临时开辟的空间、空间是可以重复利用的 递归为O(n) 时间复杂度&#xff1a;程序执行次数 消失的数字 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 思路1&#xff1a;利用连续的特点求等差和然后减去所有元素得到的就是消…...

【Android】设置全局标题栏

序言 在做项目的时候&#xff0c;有时候需要一个全局统一的标题栏&#xff0c;保证项目风格的统一&#xff0c;但是如果在每个activity上面都写一遍这个标题栏就很麻烦了&#xff0c;我们经常用的方法就是写个基类Activity&#xff0c;然后当某个Activity需要这个统一的标题栏…...

R语言的入门学习

目录 准备工作导入csv数据集选择前200行作为数据集展示数据集的前/后几N行宏观分析删除缺失值构建直方图导出为图片 R语言常见图像类型例1&#xff1a;散点图例2&#xff1a;散点矩阵图 准备工作 安装教程&#xff1a; R语言和RStudio的下载安装&#xff08;非常简便舒适&…...

【开源】基于Vue和SpringBoot的民宿预定管理系统

项目编号&#xff1a; S 058 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S058&#xff0c;文末获取源码。} 项目编号&#xff1a;S058&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 用例设计2.2 功能设计2.2.1 租客角色…...

nacos集群部署

GitHub - nacos-group/nacos-k8s: This project contains a Nacos Docker image meant to facilitate the deployment of Nacos on Kubernetes using StatefulSets. 需要修改两个文件 --- apiVersion: v1 kind: Service metadata:name: nacos-headlessnamespace: project-guli…...

9、传统计算机视觉 —— 边缘检测

本节介绍一种利用传统计算机视觉方法来实现图片边缘检测的方法。 什么是边缘检测? 边缘检测是通过一些算法来识别图像中物体之间,或者物体与背景之间的边界,也就是边缘。 边缘通常是图像中灰度变化显著的地方,标志着不同区域的分界线。 在一张图像中,边缘可以是物体的…...

Linux tc 使用

tc模拟延时丢包等网络故障依赖的内核驱动 /lib/modules/5.15.0-52-generic/kernel/net/sched/sch_netem.ko有些系统并不是默认就安装上该驱动的&#xff0c;如果没有安装该驱动&#xff0c;构造网络故障时会报错。 root:curtis# tc qdisc change dev enp4s0 root netem delay…...

从0开始学习JavaScript--JavaScript 数字与日期

JavaScript中的数字和日期是处理数值计算和时间相关任务的核心。本文将深入研究JavaScript中数字的表示、常见运算&#xff0c;以及日期对象的创建、格式化等操作&#xff0c;并通过丰富的示例代码&#xff0c;可以更全面地了解和应用这些概念。 JavaScript数字基础 JavaScri…...

从关键新闻和最新技术看AI行业发展(2023.11.6-11.19第十期) |【WeThinkIn老实人报】

Rocky Ding 公众号&#xff1a;WeThinkIn 写在前面 【WeThinkIn老实人报】旨在整理&挖掘AI行业的关键新闻和最新技术&#xff0c;同时Rocky会对这些关键信息进行解读&#xff0c;力求让读者们能从容跟随AI科技潮流。也欢迎大家提出宝贵的优化建议&#xff0c;一起交流学习&…...

计算机硬件的基本组成

一、冯诺依曼结构 存储程序&#xff1a; “存储程序”的概念是指将指令以二进制代码的形式事先输入计算机的主存储器&#xff0c;然后按其在存储器中的首地址执行程序的第一条指令&#xff0c;以后就按该程序的规定顺序执行其他指令&#xff0c;直至程序执行结束。 冯诺依曼计…...

【算法-哈希表3】四数相加2 和 赎金信

今天&#xff0c;带来哈希表相关算法的讲解。文中不足错漏之处望请斧正&#xff01; 理论基础点这里 1. 四数相加2 分析题意 求符合条件的四元组的出现次数&#xff0c;条件&#xff1a; nums1nums2nums3nums4 从四个数组中的每一个数组取一个数 num1, num2, num3, num4&am…...

wpf devexpress自定义编辑器

打开前一个例子 步骤1-自定义FirstName和LastName编辑器字段 如果运行程序&#xff0c;会通知编辑器是空。对于例子&#xff0c;这两个未命名编辑器在第一个LayoutItem(Name)。和最终用户有一个访客左右编辑器查阅到First Name和Last Name字段&#xff0c;分别。如果你看到Go…...

文档向量化工具(一):Apache Tika介绍

Apache Tika是什么&#xff1f;能干什么&#xff1f; Apache Tika是一个内容分析工具包。 该工具包可以从一千多种不同的文件类型&#xff08;如PPT、XLS和PDF&#xff09;中检测并提取元数据和文本。 所有这些文件类型都可以通过同一个接口进行解析&#xff0c;这使得Tika在…...

学习c#的第二十一天

目录 C# 泛型&#xff08;Generic&#xff09; 泛型类型参数 类型参数的约束 约束多个参数 未绑定的类型参数 类型参数作为约束 notnull 约束 class 约束 default 约束 非托管约束 委托约束 枚举约束 类型参数实现声明的接口 泛型类 泛型方法 泛型和数组 泛型…...

Michael Jordan最新报告:去中心化机器学习中的契约、不确定性和激励

‍ ‍导读 11月3日&#xff0c;智源研究院学术顾问委员会委员、机器学习泰斗Michael Jordan在以“新一代人工智能前沿”为主题的2023北京论坛 新工科专题论坛上&#xff0c;发表了题为Contracts, Uncertainty, and Incentives in Decentralized Machine Learning&#xff08;去…...

3ds Max渲染用专业显卡还是游戏显卡?

使用3dsmax建模时&#xff0c;会面临诸多选择&#xff0c;除了用vr还是cr的决策&#xff0c;硬件选择上也存在着疑问&#xff0c;比如用专业显卡还是消费级游戏显卡&#xff1f;一般来说&#xff0c;除非是特别专业的大型项目和软件&#xff0c;且预算在5位数以上&#xff0c;常…...

airlearning-ue4安装的踩坑记录

最近要安装airlearning-ue4&#xff0c;用于实现无人机仿真环境&#xff0c;该项目地址为&#xff1a;GitHub - harvard-edge/airlearning-ue4: Environment Generator for Air Learning Project. This version is build on top of UE4 game engine 由于这个项目已经完成好几年…...

uniapp优化h5项目-摇树优化,gzip压缩和删除console.log

1.摇树优化 勾选摇树优化,打包删除死代码 2.gzip压缩和删除console.log 安装插件webpack和compression-webpack-plugin webpack插件 npm install webpack4.46.0 --save-devcompression-webpack-plugin插件 npm install compression-webpack-plugin6.1.1 --save-devconst Com…...

Pycharm之配置python虚拟环境

最近给身边的人写了脚本&#xff0c;在自己电脑可以正常运行。分享给我身边的人&#xff0c;却运行不起来&#xff0c;然后把报错的截图给我看了&#xff0c;所以难道不会利用pycharm搭建虚拟的环境&#xff1f;记录一下配置的过程。 第一步&#xff1a;右键要打开的python的代…...

如何使用MybatisPlus进行数据分页显示

如何使用MybatisPlus进行数据的分页呢&#xff1f; 使用Mybatis Plus提供的分页插件来简化开发&#xff0c;在MybatisPlusInterceptor的拦截器中添加自动分页的PaginationInnerInterceptor拦截器&#xff0c;当前配置需要交给spring的bean管理&#xff0c;类上添加注解Configu…...

基于当前项目通过npm包形式暴露公共组件

1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹&#xff0c;并新增内容 3.创建package文件夹...

【项目实战】通过多模态+LangGraph实现PPT生成助手

PPT自动生成系统 基于LangGraph的PPT自动生成系统&#xff0c;可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析&#xff1a;自动解析Markdown文档结构PPT模板分析&#xff1a;分析PPT模板的布局和风格智能布局决策&#xff1a;匹配内容与合适的PPT布局自动…...

蓝桥杯 冶炼金属

原题目链接 &#x1f527; 冶炼金属转换率推测题解 &#x1f4dc; 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V&#xff0c;是一个正整数&#xff0c;表示每 V V V 个普通金属 O O O 可以冶炼出 …...

《C++ 模板》

目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板&#xff0c;就像一个模具&#xff0c;里面可以将不同类型的材料做成一个形状&#xff0c;其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式&#xff1a;templa…...

NPOI操作EXCEL文件 ——CAD C# 二次开发

缺点:dll.版本容易加载错误。CAD加载插件时&#xff0c;没有加载所有类库。插件运行过程中用到某个类库&#xff0c;会从CAD的安装目录找&#xff0c;找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库&#xff0c;就用插件程序加载进…...

MinIO Docker 部署:仅开放一个端口

MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...

关于easyexcel动态下拉选问题处理

前些日子突然碰到一个问题&#xff0c;说是客户的导入文件模版想支持部分导入内容的下拉选&#xff0c;于是我就找了easyexcel官网寻找解决方案&#xff0c;并没有找到合适的方案&#xff0c;没办法只能自己动手并分享出来&#xff0c;针对Java生成Excel下拉菜单时因选项过多导…...

【Linux手册】探秘系统世界:从用户交互到硬件底层的全链路工作之旅

目录 前言 操作系统与驱动程序 是什么&#xff0c;为什么 怎么做 system call 用户操作接口 总结 前言 日常生活中&#xff0c;我们在使用电子设备时&#xff0c;我们所输入执行的每一条指令最终大多都会作用到硬件上&#xff0c;比如下载一款软件最终会下载到硬盘上&am…...

6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础

第三周 Day 3 &#x1f3af; 今日目标 理解类&#xff08;class&#xff09;和对象&#xff08;object&#xff09;的关系学会定义类的属性、方法和构造函数&#xff08;init&#xff09;掌握对象的创建与使用初识封装、继承和多态的基本概念&#xff08;预告&#xff09; &a…...

PH热榜 | 2025-06-08

1. Thiings 标语&#xff1a;一套超过1900个免费AI生成的3D图标集合 介绍&#xff1a;Thiings是一个不断扩展的免费AI生成3D图标库&#xff0c;目前已有超过1900个图标。你可以按照主题浏览&#xff0c;生成自己的图标&#xff0c;或者下载整个图标集。所有图标都可以在个人或…...