栈和队列专题(LeetCode)

目录

  • 有效的括号
    • 题解
    • 代码加解释
  • 用队列实现栈
    • 题解
    • 代码加解释
  • 设计循环队列
    • 题解
    • 代码加解释
  • 用栈实现队列
    • 题解
    • 代码加解释

有效的括号

在这里插入图片描述

题解

左括号从s字符串中取出来放入
s中就只有右括号
那么栈顶的左括号和s的右括号匹配即可
代码中也详细解释了左括号和右括号多少的问题

代码加解释

bool isValid(char* s) 
{Stack sl;StackInit(&sl);while(*s){//先插入左括号if(*s == '('||*s == '{'||*s == '['){StackPush(&sl,*s);}else//右括号取栈顶左括号尝试匹配{if(STEmpty(&sl)){//解决右括号比左括号多的情况//s中只有右括号,top == 0StackDestroy(&sl);//释放sl指向的空间return false;}//取栈顶数据char top = STTop(&sl);//把栈顶的括号取出来和右括号匹配StackPop(&sl);//弹出栈顶数据,方便取下一个数据//不匹配if(top == '('&& *s != ')'||top == '['&&*s != ']'||top == '{'&&*s != '}'){StackDestroy(&sl);return false;}}s++;}//栈不为空,左括号的数量比右括号的数量多,数量不匹配//只有一个左括号,假//解决的是右括号和左括号一样多和左括号多的情况bool ret = STEmpty(&sl);//栈为空,top == 0,真StackDestroy(&sl);return ret; 
}

用队列实现栈

请你仅使用两个队列实现一个后入先出(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 都保证栈不为空

进阶:你能否仅用一个队列来实现栈。

题解

实现各个接口,用两个队列实现栈
主体思路还是保证一个队列是空的,一个队列是非空的
空的队列用于导数据,比如非空队列 1 2 3 4,1 2 3导到空的队列中,4直接pop,对应栈顶的删除
非空的队列直接插入数据,因为队列是尾插,也就是栈顶的插入
在这里插入图片描述
MyStack下有一个重要的说明
1.后取地址,相当于开了一个新的队列,在新的队列中许多值是未定义的,相当于随机值,所以不能后取地址
在这里插入图片描述

2.先取地址,是对原队列进行操作,指针指向原队列
在这里插入图片描述

代码加解释

//C语言要造轮子,前面的接口在上一个博客,需要的可以自取
typedef struct 
{Queue q;//队列1Queue p;//队列2
} MyStack;MyStack* myStackCreate() 
{//一个队列为空,另一个队列为有数据//把数据插入非空队列中,空的队列用来导数据MyStack* obj = (MyStack*)malloc(sizeof(MyStack));//不能和题里创建一样的指针,重定义QueueInit(&(obj->p));QueueInit(&(obj->q));//初始化队列1和队列2return obj;
}void myStackPush(MyStack* obj, int x) 
{if(!QueueEmpty(&(obj->p))){QueuePush(&(obj->p),x);//第一个队列是非空的就插入第一个队列中}   else//1.p空q非空,插入队列q 2.p空q空,这种随便插入那个队列{QueuePush(&(obj->q),x);}
}int myStackPop(MyStack* obj) 
{//你不知道q,p那个队列是空,所以要假设//用空队列导一下//假设法,假设队列p为非空,队列q为空Queue* Noempty = &(obj->p);Queue* Empty = &(obj->q);if(!QueueEmpty(&(obj->q))){Empty = &(obj->p);Noempty = &(obj->q);}   while(QueueSize(Noempty) > 1){QueuePush(Empty, QueueTop(Noempty));QueuePop(Noempty);//卡在这个地方,把对头数据取出来,然后头删,再尾插入空的队列}int top = QueueTop(Noempty);QueuePop(Noempty); //把栈顶数据取出来,返回栈顶数据//再删掉最后的栈顶数据    return top;
}int myStackTop(MyStack* obj) 
{if(!QueueEmpty(&(obj->q))){return QueueTail(&(obj->q));}  else{return QueueTail(&(obj->p));}
}bool myStackEmpty(MyStack* obj) 
{return QueueEmpty(&(obj->q)) && QueueEmpty(&(obj->p));    
}void myStackFree(MyStack* obj) 
{QueueDestroy(&(obj->q));QueueDestroy(&(obj->p));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);*/

设计循环队列

在这里插入图片描述

题解

主要多开一个空间为了解决假溢出问题
代码里也有写

队列为空 -> head == tail
在这里插入图片描述

队列为满 -> (tail+1)% (k+1) == head
%k+1 为了解决回绕问题
普通的情况tail + 1 = head
在这里插入图片描述

  • 插入数据 -> (obj->tail) %= (obj->k+1);
    tail++ 变成5又要解决回绕问题,%k+1回到0位置可以插入数据
  • 删除数据 -> obj->head %= (obj->k+1)
    head++ 变成5又要解决回绕问题,%k+1回到0位置可以删除数据
  • 取队头数据 -> obj->a[obj->head]
    head指向头直接取队头数据
  • 取队尾数据 ->
    1.return obj->a[(obj->tail-1 + obj->k+1) % (obj->k+1)]
    2.return obj->tail == 0 ? obj->a[obj->k] : obj->a[obj->tail-1]

tail是指向队尾的下一个位置
取队尾数据要tail - 1,但是tail == 0时,tail - 1就会越界,
tail == 0时要回绕到 tail == k 是队尾数据的下标

有两种方法可以理解第二种比较好理解
第一种取一个数据也比较好理解
比如tail = 0,k = 4 时,-1+5 = 4 % k+1 = 4,就取到队尾的下标了

代码加解释

typedef struct 
{int* a;int head;//指向头int tail;//指向尾int k;     
} MyCircularQueue;MyCircularQueue* myCircularQueueCreate(int k) 
{MyCircularQueue* obj = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));obj->a = (int*)malloc(sizeof(int)*(k+1));//多开一个空间,为了解决循环队列的假溢出问题//假溢出问题:比如开四个空间,head == tail是空,head == tail也是满obj->head = 0;obj->tail = 0;    obj->k = k;return obj;
}bool myCircularQueueIsEmpty(MyCircularQueue* obj) 
{return obj->head == obj->tail;    
}bool myCircularQueueIsFull(MyCircularQueue* obj)  
{// tail + 1 == head;return (obj->tail+1) % (obj->k+1) == obj->head;
}bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) 
{if(myCircularQueueIsFull(obj)){return false;}obj->a[obj->tail] = value;obj->tail++;(obj->tail) %= (obj->k+1);return true;
}bool myCircularQueueDeQueue(MyCircularQueue* obj) 
{if(myCircularQueueIsEmpty(obj)){return false;}    obj->head++;obj->head %= (obj->k+1);return true;
}int myCircularQueueFront(MyCircularQueue* obj)
{if(myCircularQueueIsEmpty(obj)){return -1;}return obj->a[obj->head];
}int myCircularQueueRear(MyCircularQueue* obj) 
{if(myCircularQueueIsEmpty(obj)){return -1;}return obj->a[(obj->tail-1 + obj->k+1) % (obj->k+1)];//return obj->tail == 0 ? obj->a[obj->k] : obj->a[obj->tail-1];
}void myCircularQueueFree(MyCircularQueue* obj) 
{free(obj->a);//先把数组释放,再把结构体释放free(obj);
}/*** Your MyCircularQueue struct will be instantiated and called as such:* MyCircularQueue* obj = myCircularQueueCreate(k);* bool param_1 = myCircularQueueEnQueue(obj, value);* bool param_2 = myCircularQueueDeQueue(obj);* int param_3 = myCircularQueueFront(obj);* int param_4 = myCircularQueueRear(obj);* bool param_5 = myCircularQueueIsEmpty(obj);* bool param_6 = myCircularQueueIsFull(obj);* myCircularQueueFree(obj);
*/

用栈实现队列

在这里插入图片描述

题解

设计一个为poplist的栈和pushlist的栈
一个栈专门插入数据
一个栈专门删除数据
StackPush(&(obj->pushlist),x)
直接入栈达到了先进的效果
将pushlist中的数据导入poplist中,先进的数据就达到先出的效果了
poplist中有数据直接出
没有数据从pushlist中导数据在出数据
所以两个栈只要有一个栈是非空的就可以出数据
只要有一个栈是非空的,就是非空队列
在这里插入图片描述

代码加解释

typedef struct 
{Stack pushlist;Stack poplist;//后进先出栈实现先进先出队列
} MyQueue;MyQueue* myQueueCreate() 
{MyQueue* obj = (MyQueue*)malloc(sizeof(MyQueue));StackInit(&(obj->pushlist));StackInit(&(obj->poplist));return obj;
}void myQueuePush(MyQueue* obj, int x) 
{//直接插入pushlist的队列,队尾入数据也就是栈顶入数据StackPush(&(obj->pushlist),x);
}int myQueuePop(MyQueue* obj) 
{int front = myQueuePeek(obj);//push pop//传过去的应该是obj,指向两个栈的结构体指针StackPop(&(obj->poplist));return front;
}int myQueuePeek(MyQueue* obj) 
{if(STEmpty(&(obj->poplist))){while(!STEmpty(&(obj->pushlist))){StackPush(&(obj->poplist),STTop(&(obj->pushlist)));StackPop(&(obj->pushlist));}}int ret = STTop(&(obj->poplist));return ret;
}bool myQueueEmpty(MyQueue* obj) 
{return STEmpty(&(obj->pushlist)) && STEmpty(&(obj->poplist));    
}void myQueueFree(MyQueue* obj) 
{StackDestroy(&(obj->pushlist));StackDestroy(&(obj->poplist));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);
*/

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

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

相关文章

Integer包装类

面试题&#xff1a; 自动装箱:把基本数据类型会自动的变成其对应的包装类 自动拆箱:把包装类自动的变成其对象的基本数据类型 package Integer;public class Demo {public static void main(String[] args) {Integer i 10;String binaryString Integer.toBinaryString(i);Str…

linux系统常用压缩和解压命令

文章目录 Ubuntu 系统中的文件压缩与解压指南一、常用的压缩和解压工具二、tar 工具三、gzip 工具四、bzip2 工具五、zip 和 unzip 工具六、7z 工具乱码批量解压脚本七、总结 Ubuntu 系统中的文件压缩与解压指南 在 Ubuntu 系统中&#xff0c;文件压缩与解压是日常操作中非常常…

C结构详解

目录 1、结构模板 1. 建立结构声明 2. 定义结构变量 3. 访问结构成员 4. 初始化结构 声明结构数组 声明和初始化结构指针 1、结构模板 1. 建立结构声明 struct book{char title[MAXTITL];char author[MAXAUTL];float value; }&#xff1b; 该声明描述了一个又两个字符…

如何成为快手外卖代理?本地生活服务平台加盟条件解析

近年来&#xff0c;以抖音、快手和小红书等为代表的互联网大厂纷纷进军本地生活领域&#xff0c;改变美团和饿了么二分天下的这一局面的同时&#xff0c;也让本地生活成为了众多创业者眼中的“香饽饽”。其中&#xff0c;快手凭借着其庞大的用户群体&#xff0c;让快手团购外卖…

华语电影新力量用短片讲述:一部好电影,影响深远

近日&#xff0c;上汽大众杯澳涞坞全球青年电影短片大赛的公益短片《首映》在澳门澳涞坞首映发布&#xff0c;这一作品不仅展示了电影人的真实生活&#xff0c;更深刻地传达了对华语电影的敬意以及对青年电影人的殷切期望。 短片《首映》的制作团队堪称豪华。资深导演杨枫担任…

达梦数据库查看字符集、页大小

1.查看字符集select UNICODE (); 0 表示 GB18030&#xff0c;1 表示 UTF-8&#xff0c;2 表示 EUC-KR 2.查看页大小select SF_GET_PAGE_SIZE(); 也可以通过管理工具去查看

HackTheBox-Machines--Popcorn

文章目录 0x01 端口扫描0x02 测试思路2.1 80端口测试 0x03 /torrent 目录文件上传测试0x04 权限提升 Popcorn 测试过程 0x01 端口扫描 (base) gryphonwsdl ~ %nmap -sC -sV 10.129.138.22 Starting Nmap 7.94 ( https://nmap.org ) at 2024-05-28 14:22 CST Nmap scan report …

【一小时学会Charles抓包详细教程】初识Charles (1)

&#x1f680; 个人主页 极客小俊 ✍&#x1f3fb; 作者简介&#xff1a;程序猿、设计师、技术分享 &#x1f40b; 希望大家多多支持, 我们一起学习和进步&#xff01; &#x1f3c5; 欢迎评论 ❤️点赞&#x1f4ac;评论 &#x1f4c2;收藏 &#x1f4c2;加关注 Charles介绍 …

一键秒删TXT文本符号,释放工作效率新高度,轻松应对海量文本处理挑战!

在这个信息爆炸的时代&#xff0c;我们每天都会面对海量的文本信息。而在处理这些文本时&#xff0c;你是否曾经因为各种符号的干扰而头疼不已&#xff1f;现在&#xff0c;我们为你带来了一款高效批量处理工具&#xff0c;它能够一键删除TXT文本中的符号&#xff0c;让你的工作…

白酒:产地的水资源与酿酒工艺的关联性

云仓酒庄豪迈白酒的酿造过程中&#xff0c;水资源与酿酒工艺之间存在着密切的关联性。水是白酒酿造的重要原料之一&#xff0c;其质量和数量直接影响着酿酒工艺的实施和酒的品质。下面我们和云仓酒庄豪迈白酒来深入探讨一下&#xff0c;产地的水资源如何与酿酒工艺产生关联。 首…

windows部署ollama+maxkb+vscode插件continue打造本地AI

windows部署ollamamaxkbvscode插件continue打造本地AI 前言下载ollamadocker desktopvscode插件continue 安装安装ollama设置环境变量 安装docker desktop部署maxkb容器 安装vscode插件模型搜索和推荐 前言 我采用docker运行maxkb&#xff0c;本地运行ollama形式。可能是windo…

VPN的详细理解

VPN&#xff08;Virtual Private Network&#xff0c;虚拟私人网络&#xff09;是一种在公共网络上建立加密通道的技术&#xff0c;通过这种技术可以使远程用户访问公司内部网络资源时&#xff0c;实现安全的连接和数据传输。以下是对VPN的详细介绍&#xff1a; 选择代理浏览器…

如何防止锂电池反充

锂电池通常用于许多需要备用电源的设备应用中&#xff0c;例如实时时钟 (RTC) 和存储设备。当锂电池不是电路中的单一电源时&#xff0c;如果电池意外连接到可为电池充电的电源&#xff0c;则存在火灾或爆炸的风险。本应用笔记提供了在备用电源开关电路中连接锂电池所需的信息&…

LangChain打造一个AI客服

最近在学习LangChain&#xff0c;langchain的第一个入门应用就是和ChatGPT结合形成的一个AI客服&#xff0c;本期文章就带大家一起认识下 LangChain LangChain是现在用得最多的AI框架&#xff0c;langchain在帮助如基于文档数据的回答、聊天机器人和代理这类的应用程序 langch…

前端使用JavaScript实现一个LRU缓存

引言 LRU&#xff08;Least Recently Used&#xff09;算法是一种广泛应用于内存管理和缓存系统的策略&#xff0c;在微前端、状态管理以及性能优化等场景下&#xff0c;合理使用缓存机制能够有效提升应用性能。本文将介绍LRU算法的基本原理&#xff0c;并通过JavaScript实现案…

三、Ollama导入大模型(.Net8+SemanticKernel+Ollama)

Ollama导入大模型 一、导入Ollama大模型1、使用run命令2、使用Modelfile方式 二、导入自定义大模型&#xff08;Ollama官网以外的大模型&#xff09;三、使用OpenWebUI导入大模型 Ollama可以导入官方提供的大模型&#xff0c;也可以导入huggingface上的自定义大模型&#xff08…

详解布隆过滤器(含面试考点)

Bloom Filter 底层逻辑主要代码实现解析&#xff08;以C为例&#xff09;优缺点应用场景面试常问问题1&#xff1a;什么是布隆过滤器&#xff1f;问题2&#xff1a;布隆过滤器如何处理误报&#xff1f;问题3&#xff1a;如何设计布隆过滤器以最小化误报率&#xff1f;问题4&…

Jetpack架构组件_2. 数据绑定库

1.理论基础 数据绑定库是一个支持库&#xff0c;可让您使用声明性格式&#xff08;而不是以程序化方式&#xff09;将布局中的界面组件绑定到应用中的数据源。 布局通常使用调用界面框架方法的代码在 activity 中定义。例如&#xff0c;以下代码会调用 findViewById() 来查找 T…

zabbix自定义监控项

文章目录 1、配置conf文件(zabbix_agent2)linuxwindows 2、配置监控项3、配置触发器4、查看监控数据 示例自定义程序 hash_tool&#xff1a;输出指定目录的哈希值 调用指令&#xff1a; hash_tool --path [指定目录] 1、配置conf文件(zabbix_agent2) linux vim /etc/zabbix/z…

安卓获取内部存储信息

目录 前言获取存储容量 前言 原生系统设置里的存储容量到底是怎么计算的&#xff0c;跟踪源码&#xff0c;涉及到VolumeInfo、StorageManagerVolumeProvider、PrivateStorageInfo、StorageStatsManager......等等&#xff0c;java上层没有办法使用简单的api获取到吗&#xff1f…