python两个队列实现一个栈_py两个栈实现队列

纯粹是为了提高专注度,逼迫自己放下手机,就来写一写这个东西。

用两个栈来实现一个队列,leetcode剑指offer第9题,链接如下

写在前面:栈:先进后出

队列:先进先出

两者都是限制存取点的线性结构。

解决问题:

用栈来实现队列。那么首先问题是,python中怎么实现栈的呢?最方便的办法就是list了。入栈:list.append() 将数据加入列表尾部

出栈:list.pop() 弹出列表最后一个元素

list 的 append 功能实现栈的 push 操作

list 的 pop 功能实现栈的 pop 操作

所以栈我们有了,题目中说让使用两个栈,我们使用一个具体例子来说明一下:现在是 队列的 push 操作,依次push了 1 2 3 4 5,那栈中的元素如下图中的(1)所示。

那如果现在要pop呢?根据队列的性质,我们应该首先pop的是1,但是我们用的是栈,如果

那个栈直接pop的话,应该pop出的是6,所以我们这个时候可以借助栈

.

栈的元素压入

栈中,那么最先进去的 1 就位于栈

的顶端了,栈

pop的结果作为队列pop的结果,那么就是正确的了。

在这个过程中栈

被用作存储栈,栈

被用作缓存栈(即将被弹出)

python代码实现:

class CQueue:

def __init__(self):

self.A,self.B = [],[]

def appendTail(self, value: int) -> None:

self.A.append(value)

def deleteHead(self) -> int:

# 缓冲区有内容,直接pop最顶层

if self.B : return self.B.pop()

# 缓冲区和存储区都空,是个空队列,返回-1

if not self.A: return -1

# 缓冲区为空,将存储区的数据压入缓冲区

while self.A:

self.B.append(self.A.pop())

return self.B.pop()

代码中可能有些迷糊的地方,总是晕晕的,第二次写不一定能写对:队列的push操作没什么可说的了,直接存储区append进来就行

至于他的pop操作:首先,缓冲区中有数据,则直接缓冲区pop就行

缓冲区没数据,存储区也没数据,那就直接空了啊,返回-1

缓冲区没数据,存储区有数据,那就说明你上一把缓冲的最早的一些数据已经pop完了,你再把存储区的数据再全部放到缓冲区去,以备待用。再缓冲区pop,完事。

有一点很重要,一定要缓冲区为空之后,存储区的数据才能再次转移。才能保证队列弹出数据的正确性。

变形金刚之问题进阶:

其实这道题也还行,我今天吧,做牛客网上京东那个算法岗的试题,有个问题是这样的:

用俩个栈模拟实现一个队列,如果栈的容量分别是O和P(O>P),那么模拟实现的队列最大容量是多少?

这个,害,菜鸟的我当然一上来就蒙了啊。首先的首先,咱们得理解啥叫容量吧?应该就是你一个劲的一个劲地push进去,不准中途pop,直到你再push进去的话,再pop出来的就不是列表正常的pop了,就破坏列表结构了。所以咱们理解起来就是:不影响队列性质的前提下,能一直pop进去的元素数目。

然后才是首先,O和P,存储区和缓存区的选择。如果P是存储区,P装满后,往O移动,移动完了之后,O没满,P为空,再不pop的前提下,P还能装P个。这个时候O虽然不是空的,但是不能往O转移,因为那样会乱了队列的弹出顺序。所以这个容量就是2P。

如果O是存储区的话,O不能直接装满,因为装满的话转移到P中,P的栈顶元素不是第一个进去O的元素,所以一开始只能装P个,O装完P个,往P里转移,O还可以装P个肯定没问题,这缓冲区P本来就有P个,pop出去,顺序没问题,O里新装的P个,也转到缓冲区再pop出去,也没问题。那如果O这次多装一个呢,装P+1个的话,P个被转移到P里(第P+2到2P+1个元素),O里还剩一个(第P+1个),那这一个(第P+1个元素)会转移到P里,那么这个时候如果我们pop O中的元素,就成功的pop出了第P+1个元素,然后再pop P里的P个元素,这个顺序是没错的。所以说第二次装P+1个没问题耶。那大胆一点,再多装一个?假设第二次装了P+2个,那前P个被移到缓冲区,O里还剩两个(第P+1,P+2个),那这个时候无论pop哪个栈里的元素,都没办法把第P+1个元素pop出来,所以不行了。所以,只能多一个,也就是容量是2P+1。

容量是2P+1的前提是,存储区在P+1的时候pop了,之前咱们实现的栈,pop是缓冲区的事哦。

所以记住了:两个栈实现队列的最大容量为 2P+1 ,其中P是较小的栈的容量,且大栈当存储区,小栈当缓冲区。大栈需要pop出第P+1个元素。

在整个出队的过程中为了实现最大容量,不仅仅只有s2在输出,在必要的时候(即第p+1元素),s1也要直接输出,但是必须明白的是,s1最多只能直接输出一个元素(即s1中最多存储P+1个元素),多出两个往上都会违反队列的先进先出原则。

参考一下哦:用两个栈模拟一个队列,栈的容量分别是O和P(O>P),讨论队列可以实现的最大容量_平凡之路-CSDN博客_用俩个栈模拟实现一个队列,如果栈的容量分别是o和p(o>p),那么模拟实现的队列最大​blog.csdn.net

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值