leetcode栈和队列三剑客

在这里插入图片描述
用队列实现栈

在这里插入图片描述
队列是先进先出的,而栈是只能在栈顶进行出栈和入栈,那我们这道题要用队列来实现栈的话,这里给的思路是两个队列,因为两个队列的话就可以相互导数据,比如我们来实现这个题目的push函数,我们的栈是只能在栈顶进行操作,那其实插入就也可以在队列的尾部进行插入,但是我们是两个队列,我们不能在空的队列进行插入,这样顺序就会乱,所以我们这里需要做的就是在不是空的队列进行插入操作。

在这里插入图片描述
那如果我们的栈要实现出栈该怎么做呢,我们先来看一下下面的这个图。

在这里插入图片描述
我们这里的出栈不是出第一个元素1,而是想办法把我们这里第一个队列的4出去,那因为队列只能在头上进行pop那我们这里可以先把第一个队列的前三个数据导入到第二个队列中,然会在pop第一个队列就可以了。代码实现就是下面这个图

在这里插入图片描述
我们的队列是始终保持一个是有数据的,一个是为空的,比如我们如果是取栈顶的元素,这里我们是确保取出不为空的队列数据的front,所以这个函数来实现也是特别的简单。

在这里插入图片描述
这道题的整个代码思路就是下面(我们这里用的是C语言,所以要自己实现一个队列)


#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>
typedef int QDataType;typedef struct QListNode
{struct QListNode* next;QDataType data;
}QNode;// 队列的结构 
typedef struct Queue
{QNode* head;QNode* tail;int size;
}Queue;// 初始化队列 
void QueueInit(Queue* q);
// 队尾入队列 
void QueuePush(Queue* q, QDataType data);
// 队头出队列 
void QueuePop(Queue* q);
// 获取队列头部元素 
QDataType QueueFront(Queue* q);
// 获取队列队尾元素 
QDataType QueueBack(Queue* q);
// 获取队列中有效元素个数 
int QueueSize(Queue* q);
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
bool QueueEmpty(Queue* q);
// 销毁队列 
void QueueDestroy(Queue* q);// 初始化队列 
void QueueInit(Queue* q)
{assert(q);q->head = q->tail = NULL;q->size = 0;}
// 队尾入队列 
void QueuePush(Queue* q, QDataType data)
{assert(q);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc fail");exit(-1);}newnode->next = NULL;newnode->data = data;if (q->head == NULL){q->head = q->tail = newnode;}else{q->tail->next = newnode;q->tail = newnode;}q->size++;
}
// 队头出队列 
void QueuePop(Queue* q)
{assert(q);assert(q->size >= 0);assert(q->head != NULL);QNode* del = q->head;q->head = q->head->next;free(del);del = NULL;if (q->head == NULL)q->tail = NULL;q->size--;
}
// 获取队列头部元素 
QDataType QueueFront(Queue* q)
{assert(q);assert(q->head);return q->head->data;
}
// 获取队列队尾元素 
QDataType QueueBack(Queue* q)
{assert(q);assert(q->head);return q->tail->data;
}
// 获取队列中有效元素个数 
int QueueSize(Queue* q)
{assert(q);return q->size;
}
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
bool QueueEmpty(Queue* q)
{assert(q);return q->head == NULL;
}
// 销毁队列 
void QueueDestroy(Queue* q)
{assert(q);QNode* cur = q->head;while (cur){QNode* next = cur->next;free(cur);cur = next;}q->head = q->tail = NULL;
}typedef struct {Queue q1;Queue q2;
} MyStack;MyStack* myStackCreate() {MyStack* q = (MyStack*)malloc(sizeof(MyStack));QueueInit(&q->q1);QueueInit(&q->q2);return q;
}void myStackPush(MyStack* obj, int x) {if(!QueueEmpty(&obj->q1)){QueuePush(&obj->q1, x);}else{QueuePush(&obj->q2, x);}
}int myStackPop(MyStack* obj) {Queue* empty = &obj->q1;Queue* nonempty = &obj->q2;if(QueueEmpty(nonempty)){empty = &obj->q2;nonempty = &obj->q1;}while(QueueSize(nonempty) > 1){QueuePush(empty, QueueFront(nonempty));QueuePop(nonempty);}int ret = QueueFront(nonempty);QueuePop(nonempty);return ret;
}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);}/*** Your MyStack struct will be instantiated and called as such:* MyStack* obj = myStackCreate();* myStackPush(obj, x);* int param_2 = myStackPop(obj);* int param_3 = myStackTop(obj);* bool param_4 = myStackEmpty(obj);* myStackFree(obj);
*/

用栈实现队列

在这里插入图片描述
有了前面的思路,我们知道栈的实现是要有两个队列才可以实现的,那同样我们如果要用栈实现队列的话,也得用两个栈来实现,这里我们的两个栈就有主要的区别,我们一个栈可以来当pop栈,还有一个栈可以当成push栈,这样的话,我们就有了分工的作用,后续在插入的时候我们只要在pop栈进行插入就可以了。

那我们先来实现一下我们该怎么初始化,初始化我们直接给两个栈

在这里插入图片描述
这里记住我们去初始化这俩个栈的时候我们是不知道该去怎么初始化,我们直接调用他们的函数就可以了,就不用去记住他们是怎么的一个样子。

在这里插入图片描述
那我们push就需要在push栈中push就可以了

在这里插入图片描述
这里的pop需要注意一些东西
如果popST为空,则将pushST的数据倒过来,就符合先进先出的顺序,如果不为空直接在栈顶进行pop就ok,但是我们这里如果一开始pop为空的,我们需要先把数据倒过来之后才可以进行下一部,我们前面就说过只有pop栈是pop的,push只是push,那我们就要进行判断,然会进行导数据这个操作。

在这里插入图片描述
下一个取出队列的元素,这个就很简单,就是复用上面的代码就可以,只是我们是取出来,不需要进行pop

那这道题就完成了,下面的就口函数我就直接给代码了(这里还是要自己实现一下栈)

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>静态实现(固定数组的长度)
//struct Stack
//{
//	int a[N];
//	int top; //栈顶的位置
//};typedef int  STDataType;
//动态实现(固定数组的长度)
typedef struct Stack
{STDataType* a;   //传递数组地址,可以动态的进行扩容int top;   //栈顶的位置int capacity;   //容量
}ST;//初始化
void StackInit(ST* ps);//销毁
void StackDestory(ST* ps);//压栈
void StackPush(ST* ps, STDataType x);//出栈
void StackPop(ST* ps);//判断栈是否为空
bool StackEmpty(ST* ps);//计算栈的大小
int StackSize(ST* ps);//初始化
void StackInit(ST* ps)
{assert(ps);ps->a = NULL;ps->capacity = 0;ps->top = 0;  //初始化top为0,则相当于从栈顶的下一个位置开始,则先赋值,再进行++操作
}//销毁
void StackDestory(ST* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->capacity = 0;ps->top = 0;
}//压栈
void StackPush(ST* ps, STDataType x)
{assert(ps);//如果当前的空间不够就需要进行扩容if (ps->capacity == ps->top){int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;ps->a = (STDataType*)realloc(ps->a, newCapacity * sizeof(STDataType));if (ps->a == NULL){printf("realloc fail\n");exit(-1);}//当前的空间等于新的空间的大小ps->capacity = newCapacity;}ps->a[ps->top] = x;ps->top++;}//出栈
void StackPop(ST* ps)
{assert(ps);assert(ps->top > 0);ps->top--;
}//判断栈是否为空
bool StackEmpty(ST* ps)
{assert(ps);return ps->top == 0;  //判断它的顶部是否为0}//计算栈的大小
int StackSize(ST* ps)
{assert(ps);return ps->top;   //返回栈顶就是元素的个数
}//获取栈顶元素
STDataType StackTop(ST* ps)
{assert(ps);assert(ps->top > 0);return ps->a[ps->top - 1];   //top是栈顶的下一个元素,想找栈顶元素则进行减一的操作
}//获取栈顶元素
STDataType StackTop(ST* ps);
typedef struct {ST pushST;ST popST;} MyQueue;MyQueue* myQueueCreate() {MyQueue* obj = (MyQueue*)malloc(sizeof(MyQueue));assert(obj);StackInit(&obj->pushST);StackInit(&obj->popST);return obj;
}void myQueuePush(MyQueue* obj, int x) {assert(obj);StackPush(&obj->pushST,x);}int myQueuePop(MyQueue* obj) {assert(obj);//如果popST为空,则将pushST的数据倒过来,就符合先进先出的顺序if(StackEmpty(&obj->popST)){while(!StackEmpty(&obj->pushST)){StackPush(&obj->popST,StackTop(&obj->pushST));StackPop(&obj->pushST);}}int front =  StackTop(&obj->popST);StackPop(&obj->popST);return front;}int myQueuePeek(MyQueue* obj) {assert(obj);//如果popST为空,则将pushST的数据倒过来,就符合先进先出的顺序if(StackEmpty(&obj->popST)){while(!StackEmpty(&obj->pushST)){StackPush(&obj->popST,StackTop(&obj->pushST));StackPop(&obj->pushST);}}return  StackTop(&obj->popST);;}bool myQueueEmpty(MyQueue* obj) {assert(obj);return StackEmpty(&obj->pushST) && StackEmpty(&obj->popST);}void myQueueFree(MyQueue* obj) {assert(obj);StackDestory(&obj->pushST);StackDestory(&obj->popST);free(obj);}
/*** Your MyQueue struct will be instantiated and called as such:* MyQueue* obj = myQueueCreate();* myQueuePush(obj, x);* int param_2 = myQueuePop(obj);* int param_3 = myQueuePeek(obj);* bool param_4 = myQueueEmpty(obj);* myQueueFree(obj);
*//*** Your MyQueue struct will be instantiated and called as such:* MyQueue* obj = myQueueCreate();* myQueuePush(obj, x);* int param_2 = myQueuePop(obj);* int param_3 = myQueuePeek(obj);* bool param_4 = myQueueEmpty(obj);* myQueueFree(obj);
*/

后面这个题比前面两道简单一点,是关于栈的。。

有效的括号

在这里插入图片描述
这个题我们用栈来实现,为什么用栈是因为这样时间复杂度就是O(N)我们只要遍历一遍就可以了,但是我们这个题目要知道考什么,一个我们必须数量进行匹配,另一个是顺序匹配,比如左括号( 得和右)进行匹配,所以我们这里需要做的就是左括号这些入栈,然后右括号进行匹配,如果匹配成功的化原来里的括号要进行出栈,然会字符s往后继续++,但是如果有一个括号比右括号不是和我们的左括号匹配的话,我们需要进行的操作就是直接返回false就可以了,如果匹配成功的话出循环就是空栈,所以我们这里就可以直接返回true,但是还是有一个问题就是,在循环里面的时候,会出现越界访问

在这里插入图片描述
越界访问出现的情况就是有右括号,然后没有一个左括号在栈里面,我们这个取top的时候就可以直接返回。

下面是这个题的代码。


#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>typedef char STDateType;
typedef struct Stack
{STDateType* a;int top;int capacity;
}ST;void Init(ST* ps);void Push(ST* ps, STDateType x);void Pop(ST* ps);STDateType Top(ST* ps);void Dstory(ST* ps);bool Empty(ST* ps);int Size(ST* ps);void Init(ST* ps)
{assert(ps);ps->a = NULL;ps->capacity = 0;ps->top = -1;
}void Push(ST* ps, STDateType x)
{assert(ps);if (ps->top + 1 == ps->capacity){int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;STDateType* tmp =(STDateType*) realloc(ps->a, sizeof(STDateType) * newcapacity);if (tmp == NULL){perror("realloc fail");exit(-1);}ps->capacity = newcapacity;ps->a = tmp;}ps->top++;ps->a[ps->top] = x;}void Pop(ST* ps)
{assert(ps);assert(ps->top >= 0);ps->top--;
}void Dstory(ST* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->capacity = ps->capacity = 0;
}STDateType Top(ST* ps)
{assert(ps);assert(ps->top>=0);return ps->a[ps->top];
}bool Empty(ST* ps)
{assert(ps);return ps->top == -1;
}int Size(ST* ps)
{assert(ps);return ps->top + 1;
}bool isValid(char* s) {ST st;Init(&st);while(*s){if(*s == '(' || *s == '[' || *s == '{'){Push(&st, *s);s++;}else{if(Empty(&st)){return false;}char top = Top(&st);Pop(&st);if((*s == ')' && top != '(')|| (*s == ']' && top != '[')|| (*s == '}' && top != '{')){return false;}s++;}}if(Empty(&st))return true;return false;
}

那今天三剑客就分享到这里,我们下次再见。

在这里插入图片描述

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

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

相关文章

CronExpression

CronTrigger配置格式: 格式: [秒] [分] [小时] [日] [月] [周] [年]序号 说明 是否必填 允许填写的值 允许的通配符 1 秒 是 0-59 , - * / 2 分 是 0-59 , - * / 3 小时 是 0-23 , - * / 4 日 是 1-31 , - * ? / L W 5 月 是 1-12 or JA…

springboot321基于java的校园服务平台设计与开发

交流学习&#xff1a; 更多项目&#xff1a; 全网最全的Java成品项目列表 https://docs.qq.com/doc/DUXdsVlhIdVlsemdX 演示 项目功能演示&#xff1a; ————————————————

Python---函数练习:编写一个打招呼程序

函数的定义-------相关链接&#xff1a;Python---函数的作用&#xff0c;定义&#xff0c;使用步骤&#xff08;调用步骤&#xff09;-CSDN博客基本语法&#xff1a; def 函数名称([参数1, 参数2, ...]):函数体...[return 返回值] 函数的调用 Python中&#xff0c;函数和变量一…

storage和正则表达式

一、Storage 1.认识Storage WebStorage主要提供了一种机制&#xff0c;可以让浏览器提供一种比cookie更直观的key、value存储方式&#xff1a; localStorage&#xff1a;本地存储&#xff0c;提供的是一种永久性的存储方法&#xff0c;在关闭掉网页重新打开时&#xff0c;存…

侧面多级菜单(一个大类、一个小类、小类下多个物体)

效果&#xff1a; 说明&#xff1a; 左右侧面板使用Animator组件控制滑入滑出。左侧面板中&#xff0c;左的左里面是大类&#xff0c;左的右有绿色的小类&#xff0c;绿色的小类下有多个真正的UI图片按钮。 要点&#xff1a; 结合了一点EasyGridBuilderPro插件的UI元素&…

2023 PostgreSQL 数据库生态大会:解读拓数派大数据计算系统及其云存储底座

11月3日-5日&#xff0c;由中国开源软件推进联盟 PostgreSQL 分会主办的中国 PostgreSQL 数据库生态大会在北京中科院软件所隆重举行。大会以”极速进化融合新生”为主题&#xff0c;从线下会场和线上直播两种方式展开&#xff0c;邀请了数十位院士、教授、高管和社群专家&…

【Ubuntu】Ubuntu20.04下安装视频播放器vlc和录屏软件ssr

【Ubuntu】Ubuntu20.04下安装视频播放器vlc和录屏软件ssr 文章目录 【Ubuntu】Ubuntu20.04下安装视频播放器vlc和录屏软件ssr1. 安装视频播放器vlc2. 安装录屏软件ssr 1. 安装视频播放器vlc sudo apt-get install vlcvlc是一款比较简洁的视频播放器&#xff0c;如下所示 2. 安…

[acwing周赛复盘] 第 94 场周赛20230311

[acwing周赛复盘] 第 94 场周赛20231118 总结5295. 三元组1. 题目描述2. 思路分析3. 代码实现 5296. 边的定向1. 题目描述2. 思路分析3. 代码实现 六、参考链接 总结 好久没做acw了&#xff0c;挺难的。T1 模拟T2 前缀和以及优化。T3 贪心 5295. 三元组 链接: 5295. 三元组…

Mybatis学习笔记-映射文件,标签,插件

目录 概述 mybatis做了什么 原生JDBC存在什么问题 MyBatis组成部分 Mybatis工作原理 mybatis和hibernate区别 使用mybatis&#xff08;springboot&#xff09; mybatis核心-sql映射文件 基础标签说明 1.namespace&#xff0c;命名空间 2.select&#xff0c;insert&a…

【动态规划】求解编辑距离问题

目录 问题描述递推关系运行实例时空复杂度优化Hirschberg 算法 问题描述 编辑距离问题是求解将⼀个字符串转换为另⼀个字符串所需的插⼊、删除、替换的最小次数。 C O M M O M → s u b C O M M U M → s u b C O M M U N → i n s C O M M U N E \mathbb{COMMOM} \overset{sub…

八个开源免费单点登录(SSO)系统

使用SSO服务可以提高多系统使用的用户体验和安全性&#xff0c;用户不必记忆多个密码、不必多次登录浪费时间。下面推荐一些市场上最好的开源SSO系统&#xff0c;可作为商业SSO替代。 单点登录&#xff08;SSO&#xff09;是一个登录服务层&#xff0c;通过一次登录访问多个应…

TensorRt推理加速框架Python API服务器部署教程以及运行Helloworld程序

一、确认cuda工具包和n卡相关驱动是否安装 在终端中输入以下命令&#xff1a; nvcc -V如果出现以下提示&#xff0c;则已经成功安装 在终端中输入以下命令&#xff1a; nvidia-smi如果出现即为成功&#xff0c;我在这里就不去介绍怎么下载cuda和驱动怎么下载了&#xff0c;…

探索NLP中的核心架构:编码器与解码器的区别

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

分类预测 | Matlab实现PSO-BiLSTM-Attention粒子群算法优化双向长短期记忆神经网络融合注意力机制多特征分类预测

分类预测 | Matlab实现PSO-BiLSTM-Attention粒子群算法优化双向长短期记忆神经网络融合注意力机制多特征分类预测 目录 分类预测 | Matlab实现PSO-BiLSTM-Attention粒子群算法优化双向长短期记忆神经网络融合注意力机制多特征分类预测分类效果基本描述程序设计参考资料 分类效果…

使用Spring Boot实现大文件断点续传及文件校验

一、简介 随着互联网的快速发展&#xff0c;大文件的传输成为了互联网应用的重要组成部分。然而&#xff0c;由于网络不稳定等因素的影响&#xff0c;大文件的传输经常会出现中断的情况&#xff0c;这时需要重新传输&#xff0c;导致传输效率低下。 为了解决这个问题&#xff…

十三、Docker的安装

0.安装Docker Docker 分为 CE 和 EE 两大版本。CE 即社区版&#xff08;免费&#xff0c;支持周期 7 个月&#xff09;&#xff0c;EE 即企业版&#xff0c;强调安全&#xff0c;付费使用&#xff0c;支持周期 24 个月。 Docker CE 分为 stable test 和 nightly 三个更新频道…

联想笔记本电脑触摸板失灵了怎么办

这里写自定义目录标题 thinkbook笔记本电脑触摸板失灵 thinkbook笔记本电脑触摸板失灵 由于重装系统&#xff0c;导致笔记本的触控板失灵&#xff0c; 网上说的办法有 1、按键盘上的ctrlf6键&#xff0c;打开触控板功能&#xff1a;无效 2、设置——>设备——>触控板&am…

【powershell】入门和示例

▒ 目录 ▒ &#x1f6eb; 导读开发环境 1️⃣ 简介用途IDE解决此系统上禁止运行脚本 2️⃣ 语法3️⃣ 实战数据库备份执行循环拷贝文件夹 &#x1f6ec; 文章小结&#x1f4d6; 参考资料 &#x1f6eb; 导读 开发环境 版本号描述文章日期2023-11-17操作系统Win10 - 22H21904…

23111709[含文档+PPT+源码等]计算机毕业设计基于Spring Boot智能无人仓库管理-进销存储

文章目录 **软件开发环境及开发工具&#xff1a;****功能介绍&#xff1a;****论文截图&#xff1a;****数据库&#xff1a;****实现&#xff1a;****代码片段&#xff1a;** 编程技术交流、源码分享、模板分享、网课教程 &#x1f427;裙&#xff1a;776871563 软件开发环境及…

SQL server从安装到入门(一)

文章目录 彻底安装怎么安装&#xff1f;Polybase要求安装orcale jre 7更新 51或更高版本&#xff1f;安装完怎么配置&#xff1f;没有SSMS&#xff1f; 熟悉一下SMSS&#xff01; 根据本人实际安装和初步使用SQL server的过程中&#xff0c;经历的一些关键性的步骤和精品文章。…