栈实现队列day05

leetcode 232 用栈实现队列

在这里插入图片描述

复习队列

  • 队列是逻辑结构,底层可以用数组实现,也可以用链表实现,不同实现有不同的取舍。

  • 队列也是数据结构的其中一种,和栈相反的是。队列是只允许在一端进行插入,在另一端进行删除的线性表。与栈一样,队列也是一种受限的数据结构

  • 队列(Queue)是一种先进先出(FIFO - First In First Out)的数据结构

  • 队列中,插入元素会发生在尾部而删除元素会发生在头部 - 先进先出原则
    Lucifer大佬的图

队列的操作

  • 插入 - 在队列的尾部添加元素
  • 删除 - 在队列的头部删除元素
  • 查看首个元素 - 返回队列头部的元素的值

队列操作的时间复杂度

跟栈一样,队列的操作都是有效率的 -> O(1)

  • 插入 - O(1)
  • 删除 - O(1)

题解

思路比较简单,使用了两个栈,一个存一个取
图抄的的lucifer老师的
题目要求用栈的原生操作来实现队列,也就是说需要用到pop和push
但是我们知道pop和push都是在栈顶的操作,而队列的enque和deque则是在队列的两端的操作,这么一看一个stack好像不太能完成。
我们来分析一下过程。
假如向栈中分别 push 四个数字 1, 2, 3, 4,那么此时栈的情况应该是

如果此时按照题目要求 pop 或者 peek的话, 应该是返回 1 才对,而 1 在栈底我们无法直接操作。如果想要返回 1,我们首先要将 2,3,4 分别出栈才行。
在这里插入图片描述
然而,如果我们这么做,1 虽然是正常返回了,但是 2,3,4 不就永远消失了么? 一种简答方法就是,将 2,3,4 存 起来。而题目又说了,只能使用栈这种数据结构,那么我们考虑使用一个额外的栈来存放弹出的 2,3,4。
在这里插入图片描述
(pop 出来不扔掉,而是存起来)

整个过程类似这样:
在这里插入图片描述
然而这一过程,我们也可以发生在push 阶段。

总之,就是我们需要在push 或者 pop 的时候,将数组在两个栈之间倒腾一次。

public class MyQueue {
    /** Initialize your data structure here. */
    private Stack<Integer> stackin=new Stack<>();//存
    private Stack<Integer> stackout=new Stack<>();//取
    public MyQueue() {

    }

    /** Push element x to the back of queue. */
    public void push(int x) {
        stackin.add(x);//调用push方法往存的栈里面添加元素

    }

    /** Removes the element from in front of queue and returns that element. */
    public int pop(){
        if (this.empty())throw new RuntimeException("空队列");//先判断队列是否为空,如果为空,抛出异常
        if (!stackout.isEmpty())//判断取的栈是不是空的,如果不是空的直接取出来
            return stackout.pop();
        else {
        /*如果取的栈是空的,就从存的栈中把里面的所有元素都放到取的栈中,因为我们存的时候先进的在栈底,我们把它倒入取的栈中时,原来栈底的元素就到栈顶了*/
            while (!stackin.isEmpty()){
                stackout.add(stackin.pop());
            }
            return stackout.pop();
        }

    }

    /** Get the front element. */
    public int peek() {//同pop方法,只不过不用往外弹
        if (this.empty())throw new RuntimeException("空队列");
        if (!stackout.isEmpty())
            return stackout.peek();
        else {
            while (!stackin.isEmpty()){
                stackout.add(stackin.pop());
            }
            return stackout.peek();
        }

    }

    /** Returns whether the queue is empty. */
    public boolean empty() {//当存的栈和取的栈都是空时,队列此时为空
        return stackout.isEmpty()&&stackin.isEmpty();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值