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

刷爆leetcode第六期

题目一 用队列实现栈

请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。

实现 MyStack 类:

void push(int x) 将元素 x 压入栈顶。
int pop() 移除并返回栈顶元素。
int top() 返回栈顶元素。
boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。

注意:

你只能使用队列的基本操作 —— 也就是 push to back、peek/pop from front、size 和 is empty 这些操作。
你所使用的语言也许不支持队列。 你可以使用 list (列表)或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/implement-stack-using-queues

 

我们先来分析下题目

要求用两个队列实现一个栈 并且实现四种操作

我们来看第一个Push操作

栈的特点是什么? 先进后出

队列的特点是什么? 先进先出

来看图

有思路了 

图上是两个队列

我们假设 注意啊 是假设

第一行的图 它就是一个栈

那么我们可以判断出 它的数据插入顺序就是 1 2 3 4 

这个时候队列的头就是栈的尾

如果我们这个时候需要删除栈的头数据应该怎么办呢?

我们都知道队列的数据只能是从头开始出

也就是说 比如要将队列前面的1 2 3 全部出完之后才能开始出 4

但是我们不可能会抛弃之前的数据啊

这个时候我们就想到了第二个队列的用处了

只需要将我Pop的数据使用第二个队列来接受就可以

实现起来的图大概是这样子

 

这个时候我们就能删除掉头数据了

如果需要再删除一个怎么办呢?

那么只需要将上面的操作再重复一次就好了

这个时候的插入数据只需要往不为空的队列插入数据就可以了

要求首元素就是返回队列的尾

要求尾元素就是返回队列的头

也就是两个步骤

1.保持一个队列为空,一个队列存数据

2.出栈,把前面的数据倒入空队列

接下来我们来实现代码

把所有的队列代码以及接口函数拷贝进去

第一步 定义结构体

我们来看这个 我们应该怎么定义我们的Stack结构体呢?

既然是两个队列的实现的

那么是不是可以放两个队列的结构在里面?

仔细一想好像可行

我们来试试

typedef struct {Queue q1;Queue q2;
} MyStack;

画个图方便大家理解

三个结构体的关系一目了然

 第二步 实现创建(初始化)

MyStack* myStackCreate() {MyStack*pst = ( MyStack*)malloc(sizeof( MyStack));if(pst==NULL){perror("malloc fail");return NULL;}QueueInit(&pst->q1);QueueInit(&pst->q2);return pst;
}

第三步 插入数据

这里要判断队列是否为空,不为空就插入数据,两个都为空就随机一个队列插入数据

看代码:

void myStackPush(MyStack* obj, int x) {if(!QueueEmpty(&obj->q1)){QueuePush(&obj->q1,x);}else{QueuePush(&obj->q2,x);}
}

第四步 删除数据

这是最难的部分,需要我们倒数据

我们先写出两个指针来判断空和非空

如果说我们的判断不正确的话 那么我们就将这两个指针翻转一下就好了

代码整体表现不变

int myStackPop(MyStack* obj) {Queue*emptyQ = &obj->q1;Queue*nonemptyQ = &obj->q2;if(!QueueEmpty(&obj->q1)){emptyQ = &obj->q2;nonemptyQ=&obj->q1;}//倒数据while(QueueSize(nonemptyQ)>1){QueuePush(emptyQ,QueueFront(nonemptyQ));QueuePop(nonemptyQ);}//记录删除值 删掉int top = QueueFront(nonemptyQ);QueuePop(nonemptyQ);return top;
}

第五步 返回头的值

这里我们可以分两种情况讨论

如果1不为空就返回1的尾值

如果2不为空就返回2的尾值

int myStackTop(MyStack* obj) {if(!QueueEmpty(&obj->q1)){return QueueBack(&obj->q1);}else{return QueueBack(&obj->q2);}
}

第六步 判空

这步就很简单,只需要判断1和2是否都为空,都为空即空

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

第七步 释放

这里要依次释放销毁,类似套娃

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

源码

typedef int QDateType;
typedef struct QueueNode
{struct QueueNode* next;QDateType date;
}QNode;
typedef struct Queue
{QNode* head;QNode* tail;int size;
}Queue;
//初始化
void QueueInit(Queue* pq);
//销毁
void QueueDestroy(Queue* pq);
//队进
void QueuePush(Queue* pq, QDateType x);
//队出
void QueuePop(Queue* pq);
//判断为空
bool QueueEmpty(Queue* pq);
//个数
int QueueSize(Queue* pq);
//队尾
QDateType QueueBack(Queue* pq);
//对头
QDateType QueueFront(Queue* pq);
//初始化
void QueueInit(Queue* pq)
{assert(pq);pq->head = pq->tail = NULL;pq->size = 0;
}
//销毁
void QueueDestroy(Queue* pq)
{assert(pq);//两个结构体依次销毁 先销毁QNodeQNode* cur = pq->head;while (cur){QNode* next = cur->next;free(cur);cur = next;}//再置空Queuepq->head = pq->tail = NULL;pq->size = 0;
}
//队进
void QueuePush(Queue* pq, QDateType x)
{assert(pq);//开辟新节点QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc fail");return;}//赋值newnode->next = NULL;newnode->date = x;//判断是否为空if (pq->head == NULL){pq->head = pq->tail = newnode;}else{pq->tail->next = newnode;pq->tail = newnode;}//个数要++pq->size++;
}
//队出
void QueuePop(Queue* pq)
{assert(pq);assert(pq->head!=NULL);//只有一个节点if (pq->head->next == NULL){free(pq->head);pq->head = pq->tail = NULL;}else{//保存下一位QNode* next = pq->head->next;free(pq->head);pq->head = next;//迭代}//个数要--pq->size--;
}
//判断为空
bool QueueEmpty(Queue* pq)
{assert(pq);return pq->size == 0;
}
//大小
int QueueSize(Queue* pq)
{assert(pq);return pq->size;
}
//队尾
QDateType QueueBack(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->tail->date;
}
//对头
QDateType QueueFront(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->head->date;
}typedef struct {Queue q1;Queue q2;
} MyStack;MyStack* myStackCreate() {MyStack*pst = ( MyStack*)malloc(sizeof( MyStack));if(pst==NULL){perror("malloc fail");return NULL;}QueueInit(&pst->q1);QueueInit(&pst->q2);return pst;
}void myStackPush(MyStack* obj, int x) {if(!QueueEmpty(&obj->q1)){QueuePush(&obj->q1,x);}else{QueuePush(&obj->q2,x);}
}int myStackPop(MyStack* obj) {Queue*emptyQ = &obj->q1;Queue*nonemptyQ = &obj->q2;if(!QueueEmpty(&obj->q1)){emptyQ = &obj->q2;nonemptyQ=&obj->q1;}//倒数据while(QueueSize(nonemptyQ)>1){QueuePush(emptyQ,QueueFront(nonemptyQ));QueuePop(nonemptyQ);}//记录删除值 删掉int top = QueueFront(nonemptyQ);QueuePop(nonemptyQ);return top;
}int myStackTop(MyStack* obj) {if(!QueueEmpty(&obj->q1)){return QueueBack(&obj->q1);}else{return 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第六期

题目一 用队列实现栈 请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。 实现 MyStack 类: void push(int x) 将元素 x 压入栈顶。 int pop() 移除…...

汇舟问卷:国外问卷调一天900

大家好,我是汇舟问卷,专注于国外问卷调查互联网项目。夏天已经来临,您是否在三伏天顶着大太阳上班,汗水浸湿了衣襟,却依然要面对繁琐的工作和无尽的压力? 在这个炎热的季节里,我们都渴望找到一…...

openresty完美替代nginx

OpenResty相较于Nginx,其优势主要体现在以下几个方面: 1、Lua脚本支持:OpenResty内置了LuaJIT(Lua的即时编译器),使得用户可以直接在Nginx配置文件中使用Lua脚本,这样可以实现更复杂的业务逻辑…...

深入解析:Element Plus 与 Vite、Nuxt、Laravel 的结合使用

在现代前端开发中,选择合适的工具和框架来提高开发效率和应用性能是至关重要的。 Element-Plus 是一个基于 Vue.js 3.0 的流行 UI组件库,它可以与多种前端和后端框架结合使用,如 Vite、Nuxt 和 Laravel。本文将深入探讨这三者与 Element Plus…...

使ssh连接Linux服务器一直不掉线

怎么可以使ssh连接Linux服务器一直不掉线 解决方法: vim /etc/profile在/etc/profile中的TMOUT改为0 export TMOUT0最后 source /etc/profile就可以了...

2024-05-29 blue-VH-driver-对外接口的并行调用-设计与思考

摘要: VH的driver的对外接口, 要做到可以并行,也就是两个不同的线程,分别调用,不能互相阻塞。 本文记录对其的思考和设计。 上下文: 2024-05-28 blue-VH-driver-需求分析及问题分析-CSDN博客 2024-05-27 blue-vh-问题点-CSDN博客 2024-05…...

ubuntu安装

1.下载镜像文件 2.打开VMware并新建虚拟机 版本选择Ubuntu 64位 磁盘容量改为40GB 点击自定义硬件,点击新CD/DVD(SATA),连接选择ISO映像文件,找到之前下载的Ubuntu镜像文件,然后关闭选项卡。 3.开启虚拟机…...

Rosetta PyRosetta 源码包 安装包 下载

--- pyrosetta_src.zip包含以下包: | --- PyRosetta4.Debug.python27.ubuntu.release-185.tar.bz2 | --- PyRosetta4.Release.python27.linux.release-215.tar.bz2 | --- PyRosetta4.Release.python38.ubuntu.release-349.tar.bz2 --- pyrosetta_whl.zip包含…...

C++ 进阶(3)虚函数表解析

个人主页:仍有未知等待探索-CSDN博客 专题分栏:C 请多多指教! 目录 一、虚函数表 二、单继承(无虚函数覆盖) 继承关系表: 对于实例:derive d 的虚函数表: 对于实例:b…...

2024年新算法-秘书鸟优化算法(SBOA)优化BP神经网络回归预测

2024年新算法-秘书鸟优化算法(SBOA)优化BP神经网络回归预测 亮点: 输出多个评价指标:R2,RMSE,MSE,MAPE和MAE 满足需求,分开运行和对比的都有对应的主函数:main_BP, main_SBOA, main_BPvsBP_SB…...

kafka-主题创建(主题操作的命令)

文章目录 1、topic主题操作的命令1.1、创建一个3分区1副本的主题1.1.1、获取 kafka-topics.sh 的帮助信息1.1.2、副本因子设置不能超过集群中broker的数量1.1.3、创建一个3分区1副本的主题1.1.4、查看所有主题1.1.5、查看主题详细描述 1、topic主题操作的命令 kafka发送消息会存…...

[日常开发] 数据库主从延迟问题

MySQL数据库主从延迟问题 无论是学习还是工作中,MySQL数据库的使用都十分地广泛。在业务中,数据库也会以集群的形式使用,所以会涉及到主从问题。 问题描述 在使用MySQL数据库的时候,在service的方法中首先向A数据表批量插入了数…...

Python高层解雇和客户活跃度量化不确定性模型

🎯要点 🎯量化不确定性模型:🖊模型检测短信编写者行为变化 | 🖊确定(商业领域中)竞争性替代方案 | 🖊确定作弊供词真实比例 | 🖊学生考试作弊 | 🖊确定零部件…...

【IOT】OrangePi+HomeAssistant+Yolov5智能家居融合

前言 本文将以OrangePi AIpro为基础,在此基础构建HomeAssistant、YOLO目标检测实现智能家居更加灵活智能的场景实现。 表头表头设备OrangePi AIpro(8T)系统版本Ubuntu 22.04.4 LTSCPU4核64位处理器 AI处理器AI算力AI算力 8TOPS算力接口HDMI2、GPIO接口、Type-C、M.2…...

Python 点云裁剪

点云裁剪 一、介绍1.1 概念1.2 函数讲解二、代码示例2.1 代码实现2.2 代码讲解三、结果示例一、介绍 1.1 概念 点云裁剪 :根据待裁剪对象的多边形体积(json文件)实现点云的裁剪。 1.2 函数讲解 下面代码示例中主要用到了两个函数。 读取待裁剪对象的多边形体积信息(json文…...

Presto 从提交SQL到获取结果 源码详解(2)

逻辑执行计划: //进入逻辑执行计划阶段 doAnalyzeQuery().new LogicalPlanner().plan(analysis);//createAnalyzePlan createAnalyzePlan(analysis, (Analyze) statement);//返回RelationPlan,(返回root根节点,逻辑树上包含输出字…...

Python的类全面系统学习

文章目录 1. 基本概念1.1 类(Class)1.2 对象(Object) 2. 类的属性和方法3. 类的继承3.1 继承的概念3.2 单继承3.3 多重继承 4. 方法重写与多态4.1 方法重写4.2 多态 5. 特殊方法与运算符重载5.1 特殊方法(魔法方法&…...

信号处理中简单实用的方法

最小二乘法拟合消除趋势项 消除趋势项函数 在MATLAB的工具箱中已有消除线性趋势项的detrend函数;再介绍以最小二乘法拟合消除趋势项的polydetrend 函数。 函数:detrend功能:消除线性趋势项 调用格式:ydetrend(x) 说明:输入参数x是带有线性趋势项的信号序列,输出…...

Jeecg | 如何解决 ERR Client sent AUTH, but no password is set 问题

最近在尝试Jeecg低代码开发,但是碰到了超级多的问题,不过总归是成功运行起来了。 下面说说碰到的最后一个配置问题:连接redis失败 Error starting ApplicationContext. To display the conditions report re-run your application with deb…...

数据容器:set(集合) 更新啦!

数据容器:set(集合) 1.集合的定义方式 {元素, 元素, 元素} # 定义集合 my_set {"欣欣向荣", "嘉嘉", "red", "欣欣向荣", "嘉嘉", "red", "欣欣向荣", "嘉嘉…...

算法入门----小话算法(1)

下面就首先从一些数学问题入手。 Q1&#xff1a; 如何证明时间复杂度O(logN) < O(N) < O(NlogN) < O(N2) < O(2N) < O(N!) < O(NN)? A&#xff1a; 如果一个以整数为参数的不等式不能很容易看出不等的关系&#xff0c;那么最好用图示或者数学归纳法。 很显…...

Vue | 自定义组件双向绑定基础用法

Vue | 自定义组件双向绑定基础用法 vue 中&#xff0c;由于单向数据流&#xff0c;常规的父子组件属性更新&#xff0c;需要 在父组件绑定相应属性&#xff0c;再绑定相应事件&#xff0c;事件里去做更新的操作&#xff0c;利用语法糖 可以减少绑定事件的操作。 这里就简单的梳…...

python使用modbustcp协议与PLC进行简单通信

AI应用开发相关目录 本专栏包括AI应用开发相关内容分享&#xff0c;包括不限于AI算法部署实施细节、AI应用后端分析服务相关概念及开发技巧、AI应用后端应用服务相关概念及开发技巧、AI应用前端实现路径及开发技巧 适用于具备一定算法及Python使用基础的人群 AI应用开发流程概…...

mongodb在游戏开发领域的优势

1、分布式id 游戏服务器里的大部分数据都是要求全局唯一的&#xff0c;例如玩家id&#xff0c;道具id。之所以有这种要求&#xff0c;是因为运营业务上需要进行合服操作&#xff0c;保证不同服的数据在进行合服之后&#xff0c;也能保证id不冲突。如果采用关系型数据库&#x…...

大数据Scala教程从入门到精通第十篇:Scala在IDEA中编写Hello World代码的简单说明

一&#xff1a;代码展示 object Main {def main(args: Array[String]): Unit {//SCALA中可以不写;//绿色的小三角达标的是这个类中有一个MAIN方法代表是可以执行的。//ctrl shift f10可以直接运行println("Hello world!")//Java中的类库我们可以直接使用System.o…...

【SPSS】基于因子分析法对水果茶调查问卷进行分析

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…...

ElasticSearch学习篇12_《检索技术核心20讲》基础篇

背景 学习极客实践课程《检索技术核心20讲》https://time.geekbang.org/column/article/215243 课程分为基础篇、进阶篇、系统案例篇 主要记录企业课程学习过程课程大纲关键点&#xff0c;以文档形式记录笔记。 内容 检索技术&#xff1a;它是更底层的通用技术&#xff0c…...

Reids高频面试题汇总总结

一、Redis基础 Redis是什么? Redis是一个开源的内存数据存储系统,它可以用作数据库、缓存和消息中间件。Redis支持多种数据结构,如字符串、哈希表、列表、集合、有序集合等,并提供了丰富的操作命令来操作这些数据结构。Redis的主要特点是什么? 高性能:Redis将数据存储在内…...

19 - grace数据处理 - 补充 - 地下水储量计算过程分解 - 冰后回弹(GIA)改正

19 - grace数据处理 - 补充 - 地下水储量计算过程分解 - 冰后回弹(GIA)改正 0 引言1 gia数据处理过程0 引言 由水量平衡方程可以将地下水储量的计算过程分解为3个部分,第一部分计算陆地水储量变化、第二部分计算地表水储量变化、第三部分计算冰后回弹改正、第四部分计算地下…...

车载客流统计设备:双目3D还原智能统计算法的应用与优势

随着城市交通的日益繁忙和公共交通系统的不断完善&#xff0c;对公交车等交通工具的客流统计和分析变得越来越重要。传统的客流统计方法往往存在效率低下、精度不足等问题&#xff0c;难以满足现代城市交通管理的需求。而基于双目3D还原智能统计算法的车载客流统计设备&#xf…...