day9 | 栈与队列 part-1 (Go) | 232 用栈实现队列、225 用队列实现栈

今日任务 

  • 栈与队列的理论基础 (介绍:代码随想录)
  • 232 用栈实现队列(题目:  . - 力扣(LeetCode))
  • 225 用队列实现栈 (题目: . - 力扣(LeetCode) )

栈与队列的理论基础

        栈 : 先进后出    队列: 后进先出

        老师给的讲解:代码随想录   这个可能适合于 c++的同学理解,我的 go 看这里是有点不明所以..


232 用栈实现队列

        请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(pushpoppeekempty):

说明:

  • 你 只能 使用标准的栈操作 —— 也就是只有 push to toppeek/pop from topsize, 和 is empty 操作是合法的。
  • 你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。

想法:

        其实我完全理解栈与队列的特性, 先进后出、先进先出嘛, 但是一开始明白这题让干嘛的,在想这是否跟语言有关啊? 下一步直接看题解Go代码,

问题:

        看了题解才明白,其实我们就是可以利用各种语言提供的数据类型, 去模拟实现栈的一个效果,栈就是要具有 push 、pop、top、empty 这几个操作.  然后再用栈去实现 队列的操作:push、pop、peek、empty.

        那么理解了题意后,才是该思考的问题了,如何用拥有栈特性的数据结构去实现拥有队列属性的数据结构呢??🤔🤔

解决思路:

        使用栈来模式队列的行为,如果仅仅用一个栈,是一定不行的,所以需要两个栈一个输入栈,一个输出栈,这里要注意输入栈和输出栈的关系。       

        就是我们将数据 push 到栈里了,这时该如何将第一个 push 到栈的数据通过 pop给先取出来呢? 我们可以借助另一个栈2,将我们另一个栈的数据 全取出来,再 push 到栈 2 里了,这时的栈 2 的元素出栈的顺序就和我们的队列相同了.

        

图片和题解参考:代码随想录

 看代码(Go):

// 先用切片模拟栈,再用两个栈的特性去模拟一个队列的特性
//  1、通过切片实现一个栈的各种操作
type MyStack []intfunc (s *MyStack) Push(v int){*s = append(*s,v)
}func (s *MyStack) Pop() int {val := (*s)[len(*s)-1]*s = (*s)[:len(*s)-1]return val
}func (s *MyStack) Peek() int {val := (*s)[len(*s)-1]return val
}func (s *MyStack) Size() int {return len(*s)
}func (s *MyStack) Empty() bool{return s.Size() == 0
}// 2、下面开始用两个栈实现队列
type MyQueue struct {inStack *MyStackoutStack *MyStack
}func Constructor() MyQueue {return MyQueue {inStack: &MyStack{},outStack: &MyStack{},}
}func (this *MyQueue) Push(x int)  {this.inStack.Push(x)
}// 在取之前,要先把入栈里的元素全都取出放到出栈里(如果出栈里仍有数据的话,肯定还是可以直接出的)
func (this *MyQueue) Pop() int {this.moveStack()return this.outStack.Pop()
}func (this *MyQueue) Peek() int {this.moveStack()return this.outStack.Peek()
}func (this *MyQueue) Empty() bool {return this.inStack.Empty() && this.outStack.Empty()
}func (this *MyQueue) moveStack() {// 如果出栈为空的时候,再将入栈里的数据全都移动到出栈里,这样保证所有数据一直按照先进先出的顺序来的if this.outStack.Empty() {for !this.inStack.Empty() {this.outStack.Push(this.inStack.Pop())}}
}

225 用队列实现栈

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

注意:

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

想法:

        做了上一题后,我们就明白该如何去用语言已有的数据结构去模拟出栈的操作,我直接用切片就能实现栈的操作哎,但是题目还是让我们用两个队列实现,主要还是想要我们理解其中该如何转换.

问题:

       两个队列该如何实现呢? 如果我们像上一题,一个输入一个输出队列模拟还真不行, 因为最后出来的还都是先进先出.

解决思路:

1、两个队列 (题目要求)

        依然还是要用两个队列来模拟栈,只不过没有输入和输出的关系,而是另一个队列完全用来备份的!如下面动画所示,用两个队列que1和que2实现队列的功能,que2其实完全就是一个备份的作用,把que1最后面的元素以外的元素都备份到que2,然后弹出最后面的元素,再把其他元素从que2导回que1.

2、一个队列 (更优)

        一个队列在模拟栈弹出元素的时候只要将队列头部的元素(除了最后一个元素外) 重新添加到队列尾部,此时再去弹出元素就是栈的顺序了。

        

 图片和题解参考:代码随想录 

// 使用1个 队列实现栈的效果type MyStack struct{  // 初始化queue []int}func Constructor() MyStack {return MyStack{queue: make([]int,0),}}func (this *MyStack) Push(x int){// 添加元素this.queue = append(this.queue,x)
}func (this *MyStack) Pop() int {// 取出元素,因为我们当前是模拟在队列里的,遵守了一个先进先出的顺序,那么为了实现栈,我们要实现后进先出的效果n := len(this.queue)-1  // 判断长度// 除了最后一个元素,其余的都重新添加到队列里for n != 0{val := this.queue[0]// 截掉第一个元素,即将加入到队尾this.queue=this.queue[1:]this.queue=append(this.queue,val)n--}// 弹出元素val := this.queue[0]this.queue = this.queue[1:]return val
}func (this *MyStack) Top() int {val := this.Pop()// 先弹出来,再添加进去,虽然这个过程也挺无语的,就是先来了个 for 循环把最后一个元素取出来了,然后再推进去.this.Push(val)return val
}func (this *MyStack) Empty() bool {return len(this.queue) == 0
}// 两个队列实现的
type MyStack struct {//创建两个队列queue1 []intqueue2 []int
}func Constructor() MyStack {return MyStack{	//初始化queue1:make([]int,0),queue2:make([]int,0),}
}func (this *MyStack) Push(x int)  {//先将数据存在queue2中this.queue2 = append(this.queue2,x)	//将queue1中所有元素移到queue2中,再将两个队列进行交换this.Move() 
}func (this *MyStack) Move(){    if len(this.queue1) == 0{//交换,queue1置为queue2,queue2置为空this.queue1,this.queue2 = this.queue2,this.queue1}else{//queue1元素从头开始一个一个追加到queue2中this.queue2 = append(this.queue2,this.queue1[0])  this.queue1 = this.queue1[1:]	//去除第一个元素this.Move()     //重复}
}func (this *MyStack) Pop() int {val := this.queue1[0]this.queue1 = this.queue1[1:]	//去除第一个元素return val}func (this *MyStack) Top() int {return this.queue1[0]	//直接返回
}func (this *MyStack) Empty() bool {
return len(this.queue1) == 0
}

我这一开始提交的可以直接通过,但是不是队列实现栈,哈哈...

// 我这下面的栈并不是由队列实现的?  感觉有点奇怪,直接就用了下标索引取值的很 easy
type MyStack struct {queue []int
}func Constructor() MyStack {return MyStack{queue: make([]int,0),}
}func (this *MyStack) Push(x int)  {this.queue = append(this.queue,x)
}func (this *MyStack) Pop() int {val := this.queue[len(this.queue) - 1]this.queue = this.queue[0:len(this.queue)-1]return val
}func (this *MyStack) Top() int {return this.queue[len(this.queue) - 1]
}func (this *MyStack) Empty() bool {return len(this.queue) == 0
}

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

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

相关文章

记一次centos合并excel,word,png,pdf为一个整体pdf的入坑爬坑过程(一直显示宋体问题)。

一、背景 原先已经简单实现了excel,word,png,pdf合成一个整体pdf的过程。并将它弄到docker容器中。 1、原先入坑的技术栈 php:7.4 (业务有涉及)php第三方包 setasign\Fpdi\Fpdi : 2.3.6 (pdf合并)libreoffice : 5.3.6.1ImageMagick: 6.9.10-68 2、…

本地PC安装eNSP Pro完成简单的WLAN实验

前言 上个月底华为更新一版eNSP Pro,新增了AC、AP、STA等设备,也就是说可以在eNSP中进行WLAN相关的实验了。之前写过一篇文章《将eNSP Pro部署在华为云是什么体验》介绍了怎么在华为云上部署eNSP Pro,这次使用本地PC机在虚拟机中安装eNSP Pr…

RF测试笔记:三阶交调失真概述及测试

1. 交调失真会带来哪些影响? 无线通信系统中,交调失真不仅会影响发射链路的性能,还会影响接收链路的性能。 对于发射链路,非线性最严重的部件非功率放大器莫属,当信号为宽带调制信号时,无论是在信号带宽内…

13 Php学习:面向对象

PHP 面向对象 面向对象(Object-Oriented,简称 OO)是一种编程思想和方法,它将程序中的数据和操作数据的方法封装在一起,形成"对象",并通过对象之间的交互和消息传递来完成程序的功能。面向对象编…

基于Python的深度学习的中文情感分析系统(V2.0),附源码

博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇…

【STL详解 —— list的介绍及使用】

STL详解 —— list的介绍及使用 list的介绍list的介绍使用list的构造list iterator的使用list capacitylist element accesslist modifiers 示例list的迭代器失效 list的介绍 list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭…

基于Docker构建CI/CD工具链(八)用nginx收集测试报告

当前,我们已经介绍了如何使用 Apifox 和 JMeter 进行测试,尽管控制台已经输出了测试结果,但在实际工作中,我们通常需要更详细的测试报告。 测试报告在测试过程中已经生成,只需将其托管起来以便查阅。如果你有现成的 C…

C++11 设计模式4. 抽象工厂(Abstract Factory)模式

问题的提出 从前面我们已经使用了工厂方法模式 解决了一些问题。 现在 策划又提出了新的需求:对于各个怪物,在不同的场景下,怪物的面板数值会发生变化, //怪物分类:亡灵类,元素类,机械类 …

MATLAB 自定义实现点云法向量和曲率计算(详细解读)(64)

MATLAB 自定义实现点云法向量和曲率计算(详细解读)(64) 一、算法介绍二、算法步骤三、算法实现1.代码 (完整,注释清晰,可直接用)2.结果一、算法介绍 首先说明: ------这里代码手动实现,不调用matlab提供的法向量计算接口,更有助于大家了解法向量和曲率的计算方法,…

docker部署Prometheus+AlertManager实现邮件告警

文章目录 一、环境准备1、硬件准备(虚拟机)2、关闭防火墙,selinux3、所有主机安装docker 二、配置Prometheus1、docker启动Prometheus 三、添加监控节点1、docker启动node-exporter 四、Prometheus配置node-exporter1、修改prometheus.yml配置…

【网站项目】摄影竞赛小程序

🙊作者简介:拥有多年开发工作经验,分享技术代码帮助学生学习,独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。🌹赠送计算机毕业设计600个选题excel文件,帮助大学选题。赠送开题报告模板&#xff…

刷题之动态规划-回文串

前言 大家好,我是jiantaoyab,开始刷动态规划的回文串类型相关的题目 动态规划5个步骤 状态表示 :dp数组中每一个下标对应值的含义是什么>dp[i]表示什么状态转移方程: dp[i] 等于什么1 和 2 是动态规划的核心步骤,…

某次众测的加解密对抗

前言 起源于某次众测中,遇到请求包响应包全密文的情况,最终实现burp中加解密。 用到的工具有 sekiro(rpc转发)flask(autodecoder自定义接口)autodecoder(burp插件转发) debug部分…

ClickHouse--18--argMin() 和argMax()函数

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 argMin() 和argMax()函数业务场景使用案例1.准备表和数据:业务场景一:查看salary 最高和最小的user业务场景二:根据更新时间获取…

【fastapi】搭建第一个fastapi后端项目

本篇文章介绍一下fastapi后端项目的搭建。其实没有什么好说的,按照官方教程来即可:https://fastapi.tiangolo.com/zh/ 安装依赖 这也是我觉得python项目的槽点之一。所有依赖都安装在本地,一旦在别人电脑上编写项目就又要安装一遍。很扯淡。…

最优算法100例之45-不用循环乘法求1-n的和

专栏主页:计算机专业基础知识总结(适用于期末复习考研刷题求职面试)系列文章https://blog.csdn.net/seeker1994/category_12585732.html 题目描述 要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句。不能用循…

【opencv】示例-neural_network.cpp 使用机器学习模块创建并训练一个简单的多层感知机(神经网络)模型...

#include <opencv2/ml/ml.hpp> // 引入OpenCV的机器学习模块using namespace std; // 使用标准命名空间 using namespace cv; // 使用OpenCV命名空间 using namespace cv::ml; // 使用OpenCV机器学习命名空间int main() {//创建随机训练数据Mat_<float> data(100, …

字符和字符串操作函数总结

索引 一 . 字符操作函数1. 字符分类函数2. 字符转换函数 二 . 字符串操作函数长度不受限制的字符串操作函数1. strcpy函数的使用和模拟实现2. strcat函数的使用和模拟实现3. strcmp函数的使用和模拟实现 长度受限制的字符串操作函数1. strncpy函数的使用2. strncat函数的使用3.…

RT-Thread 启动流程源码详解

RT-Thread 启动流程 一般了解一份代码大多从启动部分开始,同样这里也采用这种方式,先寻找启动的源头。RT-Thread 支持多种平台和多种编译器,而 rtthread_startup() 函数是 RT-Thread 规定的统一启动入口。一般执行顺 序是:系统先从启动文件开始运行,然后进入 RT-Thread 的…

vi编辑器

目录 一、文本编辑器vi命令 1.作用&#xff1a; 2.vi和vim 二、vi编辑器的三种模式 三、输入模式 四、命令模式 五、末行模式 一、文本编辑器vi命令 1.作用&#xff1a; 创建或修改文本文件 维护Linux系统中的各种配置文件 2.vi和vim vi:类UNIX操作系统的默认文本编辑器…