首页 > 其他分享 >day10| 225.用队列实现栈;232.用栈实现队列

day10| 225.用队列实现栈;232.用栈实现队列

时间:2023-04-01 12:55:07浏览次数:30  
标签:队列 self pop queue 用栈 day10 def out

题目简述:

 

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

实现 MyStack 类:

void push(int x) 将元素 x 压入栈顶。
int pop() 移除并返回栈顶元素。
int top() 返回栈顶元素。
boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。

 

思路:

1. 用collections里的deque实现

2. 初始化函数构建两个队列

3. push函数利用append直接实现功能,append到queue_in队列中

4. pop函数实现步骤--首先确认非空--把queue_in所有元素(除了最后一个)依次出列放入queue_out--交换两个队列,此时out只有一个元素--把out里面的元素pop出来

5. top函数实现--首先确认非空--直接返回倒数第一个数

6. empty函数实现,直接return队列queue_in

 

代码如下:

from collections import deque

class MyStack:

    def __init__(self):
        """
        Python普通的Queue或SimpleQueue没有类似于peek的功能
        也无法用索引访问,在实现top的时候较为困难。

        用list可以,但是在使用pop(0)的时候时间复杂度为O(n)
        因此这里使用双向队列,我们保证只执行popleft()和append(),因为deque可以用索引访问,可以实现和peek相似的功能

        in - 存所有数据
        out - 仅在pop的时候会用到
        """
        self.queue_in = deque()
        self.queue_out = deque()

    def push(self, x: int) -> None:
        """
        直接append即可
        """
        self.queue_in.append(x)


    def pop(self) -> int:
        """
        1. 首先确认不空
        2. 因为队列的特殊性,FIFO,所以我们只有在pop()的时候才会使用queue_out
        3. 先把queue_in中的所有元素(除了最后一个),依次出列放进queue_out
        4. 交换in和out,此时out里只有一个元素
        5. 把out中的pop出来,即是原队列的最后一个
        
        tip:这不能像栈实现队列一样,因为另一个queue也是FIFO,如果执行pop()它不能像
        stack一样从另一个pop(),所以干脆in只用来存数据,pop()的时候两个进行交换
        """
        if self.empty():
            return None

        for i in range(len(self.queue_in) - 1):
            self.queue_out.append(self.queue_in.popleft())
        
        self.queue_in, self.queue_out = self.queue_out, self.queue_in    # 交换in和out,这也是为啥in只用来存
        return self.queue_out.popleft()

    def top(self) -> int:
        """
        1. 首先确认不空
        2. 我们仅有in会存放数据,所以返回第一个即可
        """
        if self.empty():
            return None
        
        return self.queue_in[-1]


    def empty(self) -> bool:
        """
        因为只有in存了数据,只要判断in是不是有数即可
        """
        return len(self.queue_in) == 0

 

或者在push函数中就把数据整理成后进先出的结构,代码如下:

class MyStack:

    def __init__(self):
        """
        Initialize your data structure here.
        """
        self.queue1 = collections.deque()
        self.queue2 = collections.deque()


    def push(self, x: int) -> None:
        """
        Push element x onto stack.
        """
        self.queue2.append(x)
        while self.queue1:
            self.queue2.append(self.queue1.popleft())
        self.queue1, self.queue2 = self.queue2, self.queue1


    def pop(self) -> int:
        """
        Removes the element on top of the stack and returns that element.
        """
        return self.queue1.popleft()


    def top(self) -> int:
        """
        Get the top element.
        """
        return self.queue1[0]


    def empty(self) -> bool:
        """
        Returns whether the stack is empty.
        """
        return not self.queue1

 

 

232. 用栈实现队列

 

题目简述:

 

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

实现 MyQueue 类:

void push(int x) 将元素 x 推到队列的末尾
int pop() 从队列的开头移除并返回元素
int peek() 返回队列开头的元素
boolean empty() 如果队列为空,返回 true ;否则,返回 false。

 

思路:

1. 用到两个栈,分别为输入栈,输出栈

2. 输入栈用于压入push传入的数据;输出栈用于pop和peek操作

3. 每次pop和peek时,若输出栈为空则将输入栈的全部数据依次弹出并压入输出栈,这样输出栈从栈顶往栈底的顺序就是队列从队首往队尾的顺序

 

代码如下:

class MyQueue(object):

    def __init__(self):
        self.stack1 = []
        self.stack2 = []

    def push(self, x):
        self.stack1.append(x)

    def pop(self):
        if not self.stack2:
            while self.stack1:
                self.stack2.append(self.stack1.pop())
        return self.stack2.pop()

    def peek(self):
        if not self.stack2:
            while self.stack1:
                self.stack2.append(self.stack1.pop())
        return self.stack2[-1]

    def empty(self):
        return not self.stack1 and not self.stack2

 

总结:

1. 两个栈可以构建一个队列

2. 两个队列可以构建一个栈

 

标签:队列,self,pop,queue,用栈,day10,def,out
From: https://www.cnblogs.com/cp1999/p/17278434.html

相关文章

  • 2023-04-01-循环队列CycleSqQueue的基本操作
    //循环链表//牺牲一个单元来区分队空还是队满#include<stdio.h>#include<stdbool.h>#defineMAXSIZE6typedefstruct{intdata[MAXSIZE];intfront,rear;}CySqQueue;voidinitCySqQueue(CySqQueue*C)//初始化循环链表{C->front=0;C->rear=0;......
  • 开源优先队列FastPriorityQueue源码阅读
    FastPriorityQueue  源码连接:https://github.com/BlueRaja/High-Speed-Priority-Queue-for-C-Sharp  大致结构:  1节点在内存中的结构还是数组,且首节点为无意义节点,有效节点从索引1开始。(见FastPriorityQueue的T[]_nodes)  2维护的节点必须时固定的继承。(见FastPri......
  • Leetcode Practice --- 栈和队列
    目录155.最小栈思路解析20.有效的括号思路解析1047.删除字符串中的所有相邻重复项思路解析1209.删除字符串中的所有相邻重复项II思路解析删除字符串中出现次数>=2次的相邻字符剑指Offer09.用两个栈实现队列239.滑动窗口最大值思路解析155.最小栈设计一个支持push......
  • 2023-03-31-顺序队列SqQueue的基本操作
    //基本顺序队列#include<stdio.h>#include<stdbool.h>#defineMAXSIZE50typedefstruct{intdata[MAXSIZE];intfront,rear;}SqQueue;voidinitSqQueue(SqQueue*Q)//进行队的初始化{Q->front=0;Q->rear=0;}boolisEmpty(SqQueue......
  • 手写单调队列
    单调队列的功能单调队列,这个神奇的\(O(n)\)算法,经常有人把他和优先队列混为一谈,但实际上两者大相径庭。总的来说,单调队列有两个功能:可以从队头/队尾出队,而且出入顺序正常。可以按照增/减/自定义比较方式求出队中最值。单调队列有一个很著名的\(Sliding\)\(Window\)......
  • 多线程队列接收
    packageorg.example.file.mult;//函数值接口@FunctionalInterfacepublicinterfaceFuncationCallback{voidcallback(Stringparam);} 回调接收 packageorg.example.file.mult;importjava.util.ArrayList;publicclassFuncationCallbackImpl{......
  • 循环队列(顺序)的实现:舞伴问题
    一、问题引入舞伴配对问题:假设在周末舞会上,男士们和女士们进入舞厅时,各自排成一队。跳舞开始时,依次从男队和女队的队头各出一人配成舞伴。若两队初始人数不相同,则较长的......
  • 面试题59 - II. 队列的最大值(剑指offer)
    题目描述:请定义一个队列并实现函数max_value得到队列里的最大值,要求函数max_value、push_back和pop_front的均摊时间复杂度都是O(1)。若队列为空,pop_front和max_v......
  • 进程消息队列实例
    //write.c#include<sys/types.h>#include<sys/ipc.h>#include<sys/msg.h>#include<stdio.h>structmymesg{longmtype;//消息的类型,是一个整数且大于0......
  • 【单调队列】LeetCode 239. 滑动窗口最大值
    题目链接239.滑动窗口最大值思路单调队列的使用方法,可以参考【单调队列】LeetCode面试题59-II.队列的最大值在本题中将滑动窗口的移动看作往队列中放数和取数的过......