LeetCode 热题100——栈与队列专题(三)

一、有效的括号

20.有效的括号(题目链接)

思路:

1)括号的顺序匹配:用栈实现,遇到左括号入,遇到右括号出(保证所出的左括号与右括号对应),否则顺序不匹配。

2)括号的数量匹配:

1>左括号大于右括号:用栈实现,遇到左括号入,遇到右括号出,遍历完字符数组,此时栈不为空,则说明左括号数量大于右括号;

2>右括号大于左括号:遇到右括号出时,判断栈是否为空,若此时栈为空,说明右括号数量大于左括号;

typedef char  SDateType;
typedef struct Stack
{SDateType* a;int top;int capacity;}Stack;
//初始化栈和销毁栈
void InitStack(Stack* ps)
{assert(ps);ps->a = NULL;ps->capacity = ps->top = 0;
}
void DestoryStack(Stack* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->capacity = ps->top = 0;}//出栈和入栈
void StackPush(Stack* ps, SDateType x)
{assert(ps);//扩容if (ps->top == ps->capacity){int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;SDateType* tmp = (SDateType*)realloc( ps->a,newcapacity * sizeof(SDateType));if (tmp == NULL){perror("realloc fail:");return;}ps->a = tmp;ps->capacity = newcapacity;}//尾插ps->a[ps->top] = x;ps->top++;
}
void StackPop(Stack* ps)
{assert(ps);assert(ps->top > 0);//只少有一个元素,才能删除ps->top--;
}//栈的有效个数和栈顶元素
int  StackSize(Stack* ps)
{assert(ps);return ps->top;
}
int   StackTop(Stack* ps)
{assert(ps);assert(ps->top > 0);return ps->a[ps->top - 1];
}//栈是否为空
bool StackEmpty(Stack* ps)
{assert(ps);return ps->top == 0;
}
int isValid(char* s) {Stack ps;InitStack(&ps);while (*s){if (*s == '[' || *s == '(' || *s == '{'){StackPush(&ps, *s);s++;}else{if (StackEmpty(&ps)){return false;}char tmp = StackTop(&ps);StackPop(&ps);if ((*s == ']' && tmp != '[') ||(*s == '}' && tmp != '{') ||(*s == ')' && tmp != '(')){return false;}s++;}}if (!StackEmpty(&ps)){return false;}else {return true;}DestoryStack(&ps);
}

二、用队列实现栈 

225. 用队列复制栈(题目链接)

 

思路: 栈是后进先出,队列是先进先出。

用俩队列实现栈

1)入栈时,选择有数据的队列入数据;

2)出栈时,将有数据队列中前k-1个数据出队列,并入到空队列中,返回并出有数据队列的最后一个数据

typedef int QDateType;
typedef struct QueueNode
{QDateType val;struct QueueNode * next;
}QueueNode;
typedef struct Queue
{QueueNode *head;QueueNode *tail;QDateType size;
}Queue;// 初始化队列
void QueueInit(Queue* pq)
{assert(pq);pq->head = pq->tail = NULL;pq->size = 0;
}void QueuePush(Queue* pq, QDateType x)
{assert(pq);QueueNode* node = (QueueNode*)malloc(sizeof(QueueNode));node->val = x;node->next = NULL;if (pq->tail == NULL){pq->head = pq->tail = node;pq->size++;}else{pq->tail->next = node;pq->tail = node;pq->size++;}
}
void QueuePop(Queue* pq)
{assert(pq);assert(pq->head != NULL);//只少保证一个节点QueueNode* del = pq->head;pq->head = pq->head->next;free(del);del = NULL;pq->size--;if (pq->head == NULL)//只有一个节点处理{pq->tail = NULL;}
}// 返回队头和队尾
QDateType QueueFront(Queue* pq)
{assert(pq);return pq->head->val;
}
QDateType QueueBack(Queue* pq)
{assert(pq);return pq->tail->val;
}// 获取队列中有效元素个数
int QueueSize(Queue* pq)
{assert(pq);return pq->size;
}bool QueueEmpty(Queue* pq)
{assert(pq);return pq->head==NULL;
}void QueueDestroy(Queue* pq)
{assert(pq);QueueNode* cur = pq->head;while (cur){QueueNode* next = cur->next;free(cur);cur = next;}pq->head = pq->tail = 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(!QueueEmpty(&obj->q1)){QueuePush(&obj->q1,x);}else{QueuePush(&obj->q2,x);}
}
bool myStackEmpty(MyStack* obj) {return QueueEmpty(&obj->q1)&&QueueEmpty(&obj->q2);
}int myStackPop(MyStack* obj) {assert(!myStackEmpty(obj));Queue * empty=&obj->q1;Queue * nonempty=&obj->q2;if(!QueueEmpty(empty)){empty=&obj->q2;nonempty=&obj->q1;}while(QueueSize(nonempty)!=1){int tmp= QueueFront(nonempty);QueuePush(empty,tmp);QueuePop(nonempty);}int tmp= QueueFront(nonempty);QueuePop(nonempty);return tmp;
}int myStackTop(MyStack* obj) {assert(!myStackEmpty(obj));Queue * empty=&obj->q1;Queue * nonempty=&obj->q2;if(!QueueEmpty(empty)){empty=&obj->q2;nonempty=&obj->q1;}return QueueBack(nonempty);
}void myStackFree(MyStack* obj) {QueueDestroy(&obj->q1);QueueDestroy(&obj->q2);free(obj);}

三、用栈实现队列 

225. 用栈实现队列(题目链接)

思路: 栈是后进先出,队列是先进先出。

1)入队列:s1栈用来在栈顶入数据;

2)出队列:s2栈用来出栈顶数据,如果s2为空,则从s1出数据入到s2中去(比如;s1中的数据为1,2,3,入到s2变为3,2,1),再出s2的栈顶数据,这样就满足队列的性质了

 

typedef int  SDateType;
typedef struct Stack
{SDateType* a;int top;int capacity;}Stack;
//初始化栈和销毁栈
void InitStack(Stack* ps)
{assert(ps);ps->a = NULL;ps->capacity = ps->top = 0;
}
void DestoryStack(Stack* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->capacity = ps->top = 0;}//出栈和入栈
void StackPush(Stack* ps, SDateType x)
{assert(ps);//扩容if (ps->top == ps->capacity){int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;SDateType* tmp = (SDateType*)realloc( ps->a,newcapacity * sizeof(SDateType));if (tmp == NULL){perror("realloc fail:");return;}ps->a = tmp;ps->capacity = newcapacity;}//尾插ps->a[ps->top] = x;ps->top++;
}
void StackPop(Stack* ps)
{assert(ps);assert(ps->top > 0);//只少有一个元素,才能删除ps->top--;
}//栈的有效个数和栈顶元素
int  StackSize(Stack* ps)
{assert(ps);return ps->top;
}
int   StackTop(Stack* ps)
{assert(ps);assert(ps->top > 0);return ps->a[ps->top - 1];
}//栈是否为空
bool StackEmpty(Stack* ps)
{assert(ps);return ps->top == 0;
}typedef struct {Stack s1;Stack s2;} MyQueue;MyQueue* myQueueCreate() {MyQueue* obj=(MyQueue* )malloc(sizeof(MyQueue));InitStack(&obj->s1);InitStack(&obj->s2);return obj;}void myQueuePush(MyQueue* obj, int x) {StackPush(&obj->s1,x);
}bool myQueueEmpty(MyQueue* obj) {return StackEmpty(&obj->s1)&&StackEmpty(&obj->s2);
}int myQueuePop(MyQueue* obj) {assert(!myQueueEmpty(obj));if(StackEmpty(&obj->s2)){while(!StackEmpty(&obj->s1)){int tmp= StackTop(&obj->s1);StackPush(&obj->s2,tmp);StackPop(&obj->s1);}}int tmp= StackTop(&obj->s2);StackPop(&obj->s2);return tmp;
}int myQueuePeek(MyQueue* obj) {assert(!myQueueEmpty(obj));if(StackEmpty(&obj->s2)){while(!StackEmpty(&obj->s1)){int tmp= StackTop(&obj->s1);StackPush(&obj->s2,tmp);StackPop(&obj->s1);}}return StackTop(&obj->s2);
}void myQueueFree(MyQueue* obj) {DestoryStack(&obj->s1);DestoryStack(&obj->s2);free(obj);}

 四、设计循环队列

622.设计循环队列(题目链接) 

思路一:数组

以front为队列头下标,tail为队列尾下一个元素下标,一共k个数据,开辟k+1个整型大小空间,方便区分队列为空、为满以及一个元素的情况

1)队列为空,front=tail

2)队列为1个元素,front+1=tail

3)   队列为满,(tail+1)%(k+1)==front

 

typedef struct {int *a;int front;int rear;int n;
} MyCircularQueue;MyCircularQueue* myCircularQueueCreate(int k) {MyCircularQueue* obj=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));int * tmp=(int *)malloc(sizeof(int)*(k+1));obj->a=tmp;obj->front=0;obj->rear=0;obj->n=k;return obj;
}bool myCircularQueueIsFull(MyCircularQueue* obj) {if((obj->rear+1)%(obj->n+1)==obj->front){return true;}return false;
}bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {if(myCircularQueueIsFull( obj)){return false;}obj->a[obj->rear]=value;obj->rear++;obj->rear=obj->rear%(obj->n+1);return true;
}bool myCircularQueueIsEmpty(MyCircularQueue* obj) {if(obj->front==obj->rear){return true;}return false;
}
bool myCircularQueueDeQueue(MyCircularQueue* obj) {if(myCircularQueueIsEmpty( obj)){return false;}obj->front++;obj->front=obj->front%(obj->n+1);return true;
}int myCircularQueueFront(MyCircularQueue* obj) {if(myCircularQueueIsEmpty( obj)){return -1;}return obj->a[obj->front];
}int myCircularQueueRear(MyCircularQueue* obj) {if(myCircularQueueIsEmpty( obj)){return -1;}return  obj->a[(obj->rear-1+obj->n+1)%(obj->n+1)];
}void myCircularQueueFree(MyCircularQueue* obj) {free(obj->a);free(obj);
}

 

思路二:单向循环链表

以head为队列头节点,tail为队列尾尾节点的下一个节点,一共k个数据,开辟k+1个节点的循环单向链表,方便区分队列为空、为满以及一个元素的情况

1)队列为空,head=tail

2)队列为1个元素,head->next=tail

3)   队列为满,tail->next=head

 

typedef struct QueueNode
{int val;struct QueueNode * next;
}QueueNode;QueueNode* BuyNode(int x)
{QueueNode* node=(QueueNode*)malloc(sizeof(QueueNode));node->val=x;node->next=NULL;return node;
}
typedef struct MyCircularQueue{QueueNode *head;QueueNode *tail;QueueNode * pretail;int n;
} MyCircularQueue;MyCircularQueue* myCircularQueueCreate(int k) {MyCircularQueue* obj=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));QueueNode* node=BuyNode(0);obj->pretail=NULL;obj->head=obj->tail=node;obj->n=(k+1);QueueNode* cur=obj->tail;while(k--){QueueNode* node=BuyNode(0);cur->next=node;cur= cur->next;}cur->next=obj->head;return obj;
}bool myCircularQueueIsFull(MyCircularQueue* obj) {if(obj->tail->next==obj->head){return true;}return false;
}bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {if(myCircularQueueIsFull( obj)){return false;}obj->tail->val=value;obj->pretail=obj->tail;obj->tail=obj->tail->next;return true;
}bool myCircularQueueIsEmpty(MyCircularQueue* obj) {if(obj->head==obj->tail){return true;}return false;
}
bool myCircularQueueDeQueue(MyCircularQueue* obj) {if(myCircularQueueIsEmpty( obj)){return false;}obj->head=obj->head->next;return true;
}int myCircularQueueFront(MyCircularQueue* obj) {if(myCircularQueueIsEmpty( obj)){return -1;}return obj->head->val;
}int myCircularQueueRear(MyCircularQueue* obj) {if(myCircularQueueIsEmpty( obj)){return -1;}return  obj->pretail->val;
}void myCircularQueueFree(MyCircularQueue* obj) {while(obj->n--){QueueNode*next=obj->head->next;free(obj->head);obj->head=next;}obj->head=NULL;free(obj);
}

 

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

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

相关文章

rabbit MQ的延迟队列处理模型示例(基于SpringBoot)

说明: 生产者P 往交换机X(typedirect)会发送两种消息:一、routingKeyXA的消息(消息存活周期10s),被队列QA队列绑定入列;一、routingKeyXB的消息(消息存活周期40s&#xf…

3.计算机网络

1.重点概念 MSL(Maximum segment lifetime):TCP 报⽂最⼤⽣存时间。它是任何 TCP 报⽂在⽹络上存在的 最⻓时间,超过这个时间报⽂将被丢弃。实际应⽤中常⽤的设置是 30 秒,1 分钟和 2 分钟。 TTL(Time to …

webpack 配置

1、基础配置 // node js核心模塊 const path require(path) // 插件是需要引入使用的 const ESLintPlugin require(eslint-webpack-plugin) // 自动生成index.html const HtmlWebpackPlugin require(html-webpack-plugin); // 将css文件单独打包,在index.html中…

2023年【四川省安全员A证】复审考试及四川省安全员A证考试试题

题库来源:安全生产模拟考试一点通公众号小程序 四川省安全员A证复审考试根据新四川省安全员A证考试大纲要求,安全生产模拟考试一点通将四川省安全员A证模拟考试试题进行汇编,组成一套四川省安全员A证全真模拟考试试题,学员可通过…

LVS+Keepalived 高可用群集

一、一.Keepalived工具介绍 专为LVS和HA设计的一款健康检查工具 • 支持故障自动切换(Failover) • 支持节点健康状态检查(Health Checking) • 官方网站:http://www.keepalived.org/ 二、Keepalived工作原理 • …

区块链技术与应用 【全国职业院校技能大赛国赛题目解析】第五套智能合约安全漏洞测试

第五套题的智能合约安全漏洞测试题目 环境 : ubuntu20 Truffle v5.8.3 (core: 5.8.3) Ganache v7.8.0 Solidity v0.8.3 Node v18.16.0 Web3.js v1.8.2 前言 请在测试的时候开启ganache打开,并且在truffle的配置文件配好ganache,之前两个帖子忘说了/(ㄒoㄒ)/~~ truffle-con…

SVN 修改版本库地址url路径

一、win11用户 1. win11系统右链菜单比较优秀,如果菜单中选择“TortoiseSVN”找不到“重新定位”,如下图所示,则需要添加右键菜单: 2.添加右键菜单:选择“TortoiseSVN”,点击设置,如下图所示&a…

云原生Docker系列 | Docker私有镜像仓库公有镜像仓库使用

云原生Docker系列 | Docker私有镜像仓库&公有镜像仓库使用 1. 使用公有云镜像仓库1.1. 阿里云镜像仓库1.2. 华为云镜像仓库1.3. 腾讯云镜像仓库2. 使用Docker Hub镜像仓库3. 使用Harbor构建私有镜像仓库4. 搭建本地Registry镜像仓库1. 使用公有云镜像仓库 1.1. 阿里云镜像…

SpringCloud原理-OpenFeign篇(三、FeignClient的动态代理原理)

文章目录 前言正文一、前戏,FeignClientFactoryBean入口方法的分析1.1 从BeanFactory入手1.2 AbstractBeanFactory#doGetBean(...)中对FactoryBean的处理1.3 结论 FactoryBean#getObject() 二、FeignClientFactoryBean实现的getObject()2.1 FeignClientFactoryBean#…

hadoop 配置历史服务器 开启历史服务器查看 hadoop (十)

1. 配置了三台服务器,hadoop22, hadoop23, hadoop24 2. hadoop文件路径: /opt/module/hadoop-3.3.4 3. hadoop22机器配置历史服务器的配置文件: 文件路径:/opt/module/hadoop-3.3.4/etc/hadoop 文件名称:mapred-size.xml 新增历…

用 HLS 实现 UART

用 HLS 实现 UART 介绍 UART 是一种旧的串行通信机制,但仍在很多平台中使用。它在 HDL 语言中的实现并不棘手,可以被视为本科生的作业。在这里,我将通过这个例子来展示在 HLS 中实现它是多么容易和有趣。 因此,从概念上讲&#xf…

【日常总结】Swagger-ui 导入 showdoc (优雅升级Swagger 2 升至 3.0)

一、场景 环境: 二、存在问题 三、解决方案 四、实战 - Swagger 2 升至 3.0 (Open API 3.0) Stage 1:引入Maven依赖 Stage 2:Swagger 配置类 Stage 3:访问 Swagger 3.0 Stage 4:获取 js…

Windows系统搭建VisualSVN服务并结合内网穿透实现公网访问

目录 前言 1. VisualSVN安装与配置 2. VisualSVN Server管理界面配置 3. 安装cpolar内网穿透 3.1 注册账号 3.2 下载cpolar客户端 3.3 登录cpolar web ui管理界面 3.4 创建公网地址 4. 固定公网地址访问 总结 前言 SVN 是 subversion 的缩写,是一个开放源…

转录组学习第四弹-数据质控

数据质控 将SRR转为fastq之后,我们需要对fastq进行质量检查,排除质量不好的数据 1.质量检查,生成报告文件 ls *fastq.gz|while read id;do fastqc $id;done并行处理 ls *fastq.gz|xargs fastqc -t 102.生成 html 报告文件和对应的 zip 压缩…

electron使用electron-builder macOS windows 打包 签名 更新 上架

0. 前言 0.1 项目工程 看清目录结构,以便您阅读后续内容 0.2 参考资料 (1)macOS开发 证书等配置/打包后导出及上架 https://www.jianshu.com/p/c9c71f2f6eac首先需要为Mac App创建App ID: 填写信息如下—Description为"P…

(02)vite环境变量配置

文章目录 将开发环境和生产环境区分开环境变量vite处理环境变量loadEnv 业务代码需要使用环境变量.env.env.development.env.test修改VITE_前缀 将开发环境和生产环境区分开 分别创建三个vite 的配置文件,并将它们引入vite.config.js vite.base.config.js import…

Kubernetes Gateway API 攻略:解锁集群流量服务新维度!

Kubernetes Gateway API 刚刚 GA,旨在改进将集群服务暴露给外部的过程。这其中包括一套更标准、更强大的 API资源,用于管理已暴露的服务。在这篇文章中,我将介绍 Gateway API 资源,并以 Istio 为例来展示这些资源是如何关联的。通…

C语言scanf_s函数的使用

因为scanf函数存在缓冲区溢出的可能性;提供了scanf_s函数;增加一个参数; scanf_s最后一个参数是缓冲区的大小,表示最多读取n-1个字符; 下图代码; 读取整型数可以不指定长度;读取char&#xf…

VMware安装kali(详细版)

如果不详细,你就留言骂我! 文章目录 前言一、安装VMware二、安装KALI安装KALI配置网络总结 前言 今天更VMware安装kali 一、安装VMware VMware网址 安装之前,建议先退出360、电脑管家等杀毒软件,Win10操作系统好像还需要检查一…

HTML5生成二维码

H5生成二维码 前言二维码实现过程页面实现关键点全部源码 前言 本文主要讲解如何通过原生HTML、CSS、Js中的qrcodejs二维码生成库,实现一个输入URL按下回车后输出URL。文章底部有全部源码,需要可以自取。 实现效果图: 上述实现效果为&#…