[栈和队列]用队列实现栈

一、题目描述

原文链接:225. 用队列实现栈


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

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


二、思路分析

栈和队列的基础知识!

两种方式:
第一种利用两个队列来实现:
暂且两个队列的名称分别是queue1(主队列)和queue2(辅助队列),针对push操作的时候,先添加到辅助队列queue2中,然后把queue1的元素都放倒queue2中,然后queue1等于queue2,queue2清空,这样的话先放到queue2中,说明每次添加的元素都是queue2的队头,这样不就是后进先出了嘛!然后pop,peek,empty都可以用queue1来操作就可以了!

第二种利用单个队列来实现:
这时候我们利用双端队列就可以了,在pop方法中,我们每次把队列的头部 放到队列的尾部就可以了,注意需要移动size - 1次!最后一个元素就是栈顶!


三、AC代码

两个栈实现队列:

class MyStack {
    Queue<Integer> queue1;
    Queue<Integer> queue2;// 辅助队列

    public MyStack() {
        queue1 = new LinkedList<>();
        queue2 = new LinkedList<>();
    }
    
    public void push(int x) {
        queue2.offer(x);// 把队尾放到第一个
        while (!queue1.isEmpty()){
            queue2.offer(queue1.poll());// 把之前的元素放到queue2中!
        }
        Queue<Integer> tmp = queue1;
        queue1 = queue2;// 把结果放到queue1中
        queue2 = tmp;// 保持queue2是空元素,从而是得每次存储的元素都是队头!
    }
    
    public int pop() {
        return queue1.poll();
    }

    public int top() {
        return queue1.peek();
    }
    
    public boolean empty() {
        return queue1.isEmpty();
    }
}

/**
 * Your MyStack object will be instantiated and called as such:
 * MyStack obj = new MyStack();
 * obj.push(x);
 * int param_2 = obj.pop();
 * int param_3 = obj.top();
 * boolean param_4 = obj.empty();
 */

利用双端队列实现栈:

class MyStack {
    Deque<Integer> deque;

    public MyStack() {
        deque = new ArrayDeque<>();
    }
    
    public void push(int x) {
        deque.addLast(x);
    }
    
    public int pop() {
       int size = deque.size() - 1;// 保留最后一个元素,因为最后一个元素就是栈顶元素
       while (size-- > 0){
           deque.addLast(deque.pollFirst());
       }
       int res = deque.peekFirst();
       deque.pollFirst();
       return res;
    }

    public int top() {
        return deque.peekLast();
    }
    
    public boolean empty() {
        return deque.isEmpty();
    }
}

/**
 * Your MyStack object will be instantiated and called as such:
 * MyStack obj = new MyStack();
 * obj.push(x);
 * int param_2 = obj.pop();
 * int param_3 = obj.top();
 * boolean param_4 = obj.empty();
 */

四、总结

  • 单边队列和双端队列的用法!

感谢大家的阅读,我是Alson_Code,一个喜欢把简单问题复杂化,把复杂问题简单化的程序猿!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值