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

【Leetcode -225.用队列实现栈 -232.用栈实现队列】

Leetcode

  • Leetcode -225.用队列实现栈
  • Leetcode -232.用栈实现队列

Leetcode -225.用队列实现栈

题目:仅使用两个队列实现一个后入先出(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(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。

示例:
输入:
[“MyStack”, “push”, “push”, “top”, “pop”, “empty”]
[[], [1], [2], [], [], []]
输出:
[null, null, null, 2, 2, false]

解释:
MyStack myStack = new MyStack();
myStack.push(1);
myStack.push(2);
myStack.top(); // 返回 2
myStack.pop(); // 返回 2
myStack.empty(); // 返回 False

提示:
1 <= x <= 9
最多调用100 次 push、pop、top 和 empty
每次调用 pop 和 top 都保证栈不为空

思路:思路是先写一个队列的数据结构,我们知道,栈的结构是先进后出,而队列的结构是先进先出,所以我们可以用两个队列,一个队列的数据导到另外一个队列中,然后留最后一个,这最后一个就是要出栈的数据,出栈就是这样实现;而入栈就是直接找到非空的队列入即可;

例如两个队列实现入栈,如果两个都为空,就随便进一个:

在这里插入图片描述
在这里插入图片描述

入栈完成后,如果要出栈,就将q1的5个数据的前4个导入q2中:

在这里插入图片描述

再出q1中的数据即可;
下面参考代码的实现:

创建队列的数据结构,以及实现队列的基本操作

		typedef int QDataType;typedef struct QueueNode{struct QueueNode* next;QDataType data;}QNode;typedef struct Queue{QNode* phead;QNode* ptail;QDataType size;}Queue;//初始化队列void QueueInit(Queue* pq){assert(pq);pq->phead = NULL;pq->ptail = NULL;pq->size = 0;}//入队void QueuePush(Queue* pq, QDataType x){assert(pq);//新节点QNode* newnode = (QNode*)malloc(sizeof(QNode));assert(newnode);newnode->data = x;newnode->next = NULL;//队列为空if (pq->ptail == NULL){assert(pq->phead == NULL);pq->phead = pq->ptail = newnode;}//队列不为空else{pq->ptail->next = newnode;pq->ptail = newnode;}pq->size++;}//判断队列是否为空bool QIsEmpty(Queue* pq){assert(pq);return pq->phead == NULL && pq->ptail == NULL;}//出队void QueuePop(Queue* pq){assert(pq);assert(!QIsEmpty(pq));//一个节点if (pq->phead->next == NULL){free(pq->phead);pq->phead = pq->ptail = NULL;}//多个节点else{//头删QNode* next = pq->phead->next;free(pq->phead);pq->phead = next;}pq->size--;}//获取队头QDataType QueueFront(Queue* pq){assert(pq);assert(!QIsEmpty(pq));return pq->phead->data;}//获取队尾QDataType QueueBack(Queue* pq){assert(pq);assert(!QIsEmpty(pq));return pq->ptail->data;}//获取队列的长度int Qsize(Queue* pq){assert(pq);return pq->size;}//释放队列void QueueDestroy(Queue* pq){assert(pq);QNode* cur = pq->phead;while (cur){QNode* next = cur->next;free(cur);cur = next;}pq->phead = pq->ptail = NULL;pq->size = 0;}

定义两个队列

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

初始化两个队列

		MyStack* myStackCreate(){MyStack* obj = (MyStack*)malloc(sizeof(MyStack));QueueInit(&obj->q1);QueueInit(&obj->q2);return obj;}

两个队列实现入栈

		void myStackPush(MyStack* obj, int x){//哪个队列不为空就入哪个队列if (!QIsEmpty(&obj->q1)){QueuePush(&obj->q1, x);}else{QueuePush(&obj->q2, x);}}

两个队列实现出栈

		int myStackPop(MyStack* obj){//假设q1为空,q2不空Queue* pEmpty = &obj->q1;Queue* pNonEmpty = &obj->q2;//如果假设错误,就改正if (!QIsEmpty(&obj->q1)){pNonEmpty = &obj->q1;pEmpty = &obj->q2;}//导数据,将非空队列中的数据导入空的队列中,非空队列留最后一个数据,即是栈顶的数据while (Qsize(pNonEmpty) > 1){QueuePush(pEmpty, QueueFront(pNonEmpty));QueuePop(pNonEmpty);}//记录栈顶的数据,然后出栈,最后返回这个数据int top = QueueFront(pNonEmpty);QueuePop(pNonEmpty);return top;}

获取两个队列实现的栈顶数据

		int myStackTop(MyStack* obj){//获取栈顶的数据即是获取非空队列的队尾数据//我们上面实现了获取队列的队尾的数据,所以直接调用函数即可if (!QIsEmpty(&obj->q1)){return QueueBack(&obj->q1);}else{return QueueBack(&obj->q2);}}

判断两个队列是否是空队列,即是否是空栈

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

释放两个队列的内存

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

Leetcode -232.用栈实现队列

题目:仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):

实现 MyQueue 类:
void push(int x) 将元素 x 推到队列的末尾
int pop() 从队列的开头移除并返回元素
int peek() 返回队列开头的元素
boolean empty() 如果队列为空,返回 true ;否则,返回 false
说明:
你 只能 使用标准的栈操作 —— 也就是只有 push to top, peek / pop from top, size, 和 is empty 操作是合法的。
你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。

示例 1:
输入:
[“MyQueue”, “push”, “push”, “peek”, “pop”, “empty”]
[[], [1], [2], [], [], []]
输出:
[null, null, null, 1, 1, false]

解释:
MyQueue myQueue = new MyQueue();
myQueue.push(1); // queue is: [1]
myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue)
myQueue.peek(); // return 1
myQueue.pop(); // return 1, queue is [2]
myQueue.empty(); // return false

提示:
1 <= x <= 9
最多调用 100 次 push、pop、peek 和 empty
假设所有操作都是有效的 (例如,一个空的队列不会调用 pop 或者 peek 操作)

思路:思路是先写一个栈的数据结构,再定义两个栈,一个pushst用来实现入队,另一个popst用来实现出队;

例如实现入队:

在这里插入图片描述
将数据入栈到pushst中:

在这里插入图片描述
需要出队列的时候,如果popst为空,就将pushst的数据入栈到popst中:

在这里插入图片描述

此时的1就是队头,1,2,3,4就是入队的顺序;
下面参考代码的实现:

实现栈的数据结构,以及栈的基本操作

		typedef int STDataType;typedef struct Stack{STDataType* stack;int top;int capacity;}ST;//初始化void STInit(ST* pst){assert(pst);pst->stack = NULL;pst->top = 0;pst->capacity = 0;}//判断是否为空栈bool STIsEmpty(ST* pst){return pst->top == 0;}//进栈void STPushTop(ST* pst, STDataType x){assert(pst);//检查容量if (pst->top == pst->capacity){int len = pst->capacity == 0 ? 4 : pst->capacity * 2;STDataType* newstack = (STDataType*)realloc(pst->stack, sizeof(ST) * len);assert(newstack);pst->capacity = len;pst->stack = newstack;}pst->stack[pst->top] = x;pst->top++;}//出栈void STPopTop(ST* pst){assert(pst);assert(!STIsEmpty(pst));pst->top--;}//获取栈顶的元素STDataType STTop(ST* pst){assert(pst);assert(!STIsEmpty(pst));return pst->stack[pst->top - 1];}//销毁栈void STDestroy(ST* pst){assert(pst);free(pst->stack);pst->stack = NULL;pst->capacity = pst->top = 0;}

定义两个栈,一个栈pushst是专门入数据,另一个popst是专门出数据

		typedef struct{ST pushst;ST popst;} MyQueue;

给两个栈初始化

		MyQueue* myQueueCreate(){MyQueue* obj = (MyQueue*)malloc(sizeof(MyQueue));STInit(&obj->pushst);STInit(&obj->popst);return obj;}

两个栈实现入队列,只需要入pushst的栈即可

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

从队列的开头移除并返回元素,与下面两个栈实现返回队列的队头数据相似,我们可以直接调用 myQueuePeek 函数,返回队头的元素后,再移除队头

		int myQueuePop(MyQueue* obj){int front = myQueuePeek(obj);STPopTop(&obj->popst);return front;}

两个栈实现返回队列的队头数据

		int myQueuePeek(MyQueue* obj){//如果popst栈为空,就将pushst的数据导过来if (STIsEmpty(&obj->popst)){while (!STIsEmpty(&obj->pushst)){STPushTop(&obj->popst, STTop(&obj->pushst));STPopTop(&obj->pushst);}}//返回popst的栈顶元素,即是队列的头return STTop(&obj->popst);}

两个栈实现判断队列是否是空,判断两个栈是否为空即可

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

释放两个栈的内存

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

相关文章:

【Leetcode -225.用队列实现栈 -232.用栈实现队列】

Leetcode Leetcode -225.用队列实现栈Leetcode -232.用栈实现队列 Leetcode -225.用队列实现栈 题目&#xff1a;仅使用两个队列实现一个后入先出&#xff08;LIFO&#xff09;的栈&#xff0c;并支持普通栈的全部四种操作&#xff08;push、top、pop 和 empty&#xff09;。 …...

悟道3.0全面开源!LeCun VS Max 智源大会最新演讲

夕小瑶科技说 原创 作者 | 小戏 2023 年智源大会如期召开&#xff01; 这场汇集了 Geoffery Hinton、Yann LeCun、姚期智、Joseph Sifakis、Sam Altman、Russell 等一众几乎是 AI 领域学界业界“半壁江山”的大佬们的学术盛会&#xff0c;聚焦 AI 领域的前沿问题&#xff0c…...

2023蓝桥杯大学A组C++决赛游记+个人题解

Day0 发烧了一晚上没睡着&#xff0c;感觉鼻子被打火机烧烤一样难受&#xff0c;心情烦躁 早上6点起来吃了个早饭&#xff0c;思考能力完全丧失了&#xff0c;开始看此花亭奇谭 看了六集&#xff0c;准备复习数据结构考试&#xff0c;然后秒睡 一睁眼就是下午2点了 挂了个…...

wkhtmltopdf踩坑记录

1. 不支持writing-mode。 需求是文字纵向排列&#xff0c;内容从左到右&#xff0c;本来用的是writing-mode: tb-rl;&#xff0c;插件转pdf后发现失效。 解决方法&#xff1a; 让每一列文字单独用一个div容器包裹&#xff0c;对它的宽度进行限制&#xff0c;控制每一行只能出现…...

贪心算法part2 | ● 122.买卖股票的最佳时机II ● 55. 跳跃游戏 ● 45.跳跃游戏II

文章目录 122.买卖股票的最佳时机II思路思路代码官方题解困难 55. 跳跃游戏思路思路代码官方题解代码困难 45.跳跃游戏II思路思路代码困难 今日收获 122.买卖股票的最佳时机II 122.买卖股票的最佳时机II 思路 局部最优&#xff1a;将当天价格和前一天比较&#xff0c;价格涨…...

[C++]异常笔记

我不怕练过一万种腿法的对手,就怕将一种腿法 练一万次的对手。 什么是C的异常 在C中&#xff0c;异常处理通常使用try-catch块来实现。try块用于包含可能会抛出异常的代码&#xff0c;而catch块用于捕获并处理异常。当异常被抛出时&#xff0c;程序会跳过try块中未执行…...

浅谈一级机电管道设计中的压力与介质温度

管道设计是工程设计中的一个非常重要的部分&#xff0c;管道的设计需要考虑到许多因素&#xff0c;其中就包括管道设计压力分类和介质温度分类。这两个因素是在设计管道时必须非常严格考虑的&#xff0c; 首先是管道设计压力分类。在管道设计中&#xff0c;根据工作要求和要传输…...

Docker网络模型(八)使用 macvlan 网络

使用 macvlan 网络 一些应用程序&#xff0c;特别是传统的应用程序或监控网络流量的应用程序&#xff0c;期望直接连接到物理网络。在这种情况下&#xff0c;你可以使用 macvlan 网络驱动为每个容器的虚拟网络接口分配一个MAC地址&#xff0c;使其看起来像一个直接连接到物理网…...

控制视图内容的位置

文本域中的提示内容在默认情况下是垂直居中的&#xff0c;要改变文本在文本域中的位置&#xff0c;可以使用android:gravity来实现。 利用android:gravity可以指定如何在视图中放置视图内容&#xff0c;例如&#xff0c;如何在文本域中放置文本。 如果希望视图文本显示在上方&a…...

【分布式系统与一致性协议】

分布式系统与一致性协议 CAP原理APCPCA总结BASE理论 一致性拜占庭将军问题 分布式系统是一个硬件或软件组件分布在不同的网络计算机上&#xff0c;彼此之间仅仅通过消息传递进行通信和协调的系统。 分布式系统的设计目标一般包含如下&#xff1a; 可用性&#xff1a;可用性是分…...

音视频领域的未来发展方向展望

文章目录 音视频领域的未来发展方向全景音视频技术虚拟现实和增强现实的区别 人工智能技术可视化智能分析智能语音交互图像识别和视频分析技术 语音处理智能推荐技术远程实时通信 流媒体技术未来方向 音视频领域的未来发展方向 全景音视频技术&#xff1a;全景音视频技术是近年…...

时间同步/集群时间同步/在线/离线

目录 一、能够连接外网 二、集群不能连接外网--同步其它服务器时间 一、能够连接外网 1.介绍ntp时间协议 NTP&#xff08;Network Time Protocol&#xff09;网络时间协议&#xff0c;是用来使计算机时间同步的一种协议&#xff0c;它可以使计算机对其服务器或时钟源做同步…...

基于BP神经网络对MNIST数据集检测识别(numpy版本)

基于BP神经网络对MNIST数据集检测识别 1&#xff0e;作者介绍2&#xff0e;BP神经网络介绍2.1 BP神经网络 3&#xff0e;BP神经网络对MNIST数据集检测实验3.1 读取数据集3.2 前向传播3.3 损失函数3.4 构建神经网络3.5 训练3.6 模型推理 4&#xff0e;完整代码 1&#xff0e;作者…...

HTML5-创建HTML文档

HTML5中的一个主要变化是&#xff1a;将元素的语义与元素对其内容呈现结果的影响分开。从原理上讲这合乎情理。HTML元素负责文档内容的结构和含义&#xff0c;内容的呈现则由应用于元素上的CSS样式控制。下面介绍最基础的HTML元素&#xff1a;文档元素和元数据元素。 一、构建…...

Vue中Axios的封装和API接口的管理

一、axios的封装 在vue项目中&#xff0c;和后台交互获取数据这块&#xff0c;我们通常使用的是axios库&#xff0c;它是基于promise的http库&#xff0c;可运行在浏览器端和node.js中。他有很多优秀的特性&#xff0c;例如拦截请求和响应、取消请求、转换json、客户端防御XSR…...

MLIR面试题

1、请简要解释MLIR的概念和用途&#xff0c;并说明MLIR在编译器领域中的重要性。 MLIR(Multi-Level Intermediate Representation)是一种多级中间表示语言&#xff0c;提供灵活、可扩展和可优化的编译器基础设施。MLIR的主要目标是为不同的编程语言、领域专用语言(DSL)和编译器…...

***杨辉三角_yyds_LeetCode_python***

1.题目描述&#xff1a; 给定一个非负整数 numRows&#xff0c;生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 示例 1: 输入: numRows 5 输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]] 示例 2: 输入: numRows …...

Mac使用DBeaver连接达梦数据库

Mac使用DBeaver连接达梦数据库 下载达梦驱动包 达梦数据库 在下载页面随便选择一个系统并下载下来。 下载下来的是zip的压缩包解压出来就是一个ISO文件&#xff0c;然后我们打开ISO文件进入目录&#xff1a;/dameng/source/drivers/jdbc 进入目录后找到这几个驱动包&#x…...

spring.expression 随笔0 概述

0. 我只是个普通码农&#xff0c;不值得挽留 Spring SpEL表达式的使用 常见的应用场景:分布式锁的切面借助SpEL来构建key 比较另类的的应用场景:动态校验 个人感觉可以用作控制程序的走向&#xff0c;除此之外&#xff0c;spring的一些模块的自动配置类&#xff0c;也会在Cond…...

从Cookie到Session: Servlet API中的会话管理详解

文章目录 一. Cookie与Session1. Cookie与Session2. Servlet会话管理操作 二. 登录逻辑的实现 一. Cookie与Session 1. Cookie与Session 首先, 在学习过 HTTP 协议的基础上, 我们需要知道 Cookie 是 HTTP 请求报头中的一个关键字段, 本质上是浏览器在本地存储数据的一种机制,…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

React第五十七节 Router中RouterProvider使用详解及注意事项

前言 在 React Router v6.4 中&#xff0c;RouterProvider 是一个核心组件&#xff0c;用于提供基于数据路由&#xff08;data routers&#xff09;的新型路由方案。 它替代了传统的 <BrowserRouter>&#xff0c;支持更强大的数据加载和操作功能&#xff08;如 loader 和…...

前端倒计时误差!

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

遍历 Map 类型集合的方法汇总

1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

【AI学习】三、AI算法中的向量

在人工智能&#xff08;AI&#xff09;算法中&#xff0c;向量&#xff08;Vector&#xff09;是一种将现实世界中的数据&#xff08;如图像、文本、音频等&#xff09;转化为计算机可处理的数值型特征表示的工具。它是连接人类认知&#xff08;如语义、视觉特征&#xff09;与…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)

🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...

uniapp中使用aixos 报错

问题&#xff1a; 在uniapp中使用aixos&#xff0c;运行后报如下错误&#xff1a; AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...

[Java恶补day16] 238.除自身以外数组的乘积

给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O(n) 时间复杂度…...

tree 树组件大数据卡顿问题优化

问题背景 项目中有用到树组件用来做文件目录&#xff0c;但是由于这个树组件的节点越来越多&#xff0c;导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多&#xff0c;导致的浏览器卡顿&#xff0c;这里很明显就需要用到虚拟列表的技术&…...