题目要求

Implement the following operations of a queue using stacks.

push(x) -- Push element x to the back of queue.
pop() -- Removes the element from in front of queue.
peek() -- Get the front element.
empty() -- Return whether the queue is empty.
Notes:
You must use only standard operations of a stack -- which means only push to top, peek/pop from top, size, and is empty operations are valid.
Depending on your language, stack may not be supported natively. You may simulate a stack by using a list or deque (double-ended queue), as long as you use only standard operations of a stack.
You may assume that all operations are valid (for example, no pop or peek operations will be called on an empty queue).

使用队列来模拟实现一个栈。
栈是指先进后出的数据结构,而队列则是先进先出的数据结构。
假设我们分别往栈和队列中顺序输入[1,2,3],那么栈的输出是[3,2,1],而队列的输出的[1,2,3]。

队列的API包括在队列尾插入数据,输出队列头的数据,查看队列的长度,队列是否为空。

那么我们现在看一下如何通过队列来实现栈的操作。

方法一:两个队列

当插入数据中时,固定往非空的那个队列插入数据。(如果两个队列的值都为空,那么就任选一个队列插入即可)。当想要获得栈顶数据或者执行栈的pop操作时,那么就将队列中的值逐个输出到另一个队列中,并输出原队列中最后一个元素的值。

下面用图形展示一下:
1.向数据结构中插入1,因为此时两个队列总都为空,因此任选一个队列插入

clipboard.png

2.向数据结构中插入2和3,因为此时队列一非空,因此插入队列一

clipboard.png

3.模拟pop操作,这是需要将队列一的内容输出再输入到队列二中并丢弃队列1中最后一个元素,即为3

clipboard.png

4.模拟top操作,类似于pop,将非空队列的内容逐个转移至空队列,并记录最后的一个元素返回,即为2

clipboard.png

代码如下:

public class Stack {

    LinkedList<Integer> queue1 = new LinkedList<Integer>();
    LinkedList<Integer> queue2 = new LinkedList<Integer>();
    
    /** Push element x onto stack. */
    public void push(int x) {
        if(queue1.isEmpty()){
            queue2.offer(x);
        }else{
            queue1.offer(x);
        }
    }
    
    /** Removes the element on top of the stack and returns that element. */
    public int pop() {
        int top = 0;
        if(queue1.isEmpty()){
            while(queue2.size() > 1){
                top = queue2.poll();
                queue1.offer(top);
            }
            top = queue2.poll();
        }else{
            while(queue1.size() > 1){
                top = queue1.poll();
                queue2.offer(top);
            }
            top = queue1.poll();
        }
        return top;
    }
    
    /** Get the top element. */
    public int top() {
        int top = 0;
        if(queue1.isEmpty()){
            while(!queue2.isEmpty()){
                top = queue2.poll();
                queue1.offer(top);
            }
        }else{
            while(!queue1.isEmpty()){
                top = queue1.poll();
                queue2.offer(top);
            }
        }
        return top;
    }
    
    /** Returns whether the stack is empty. */
    public boolean empty() {
        return queue1.isEmpty() && queue2.isEmpty();
    }
    
}

思路二:单个队列模拟栈

思路一使用两个队列从而确保值从队列中丢出的过程不会丢失。但是其实一个队列已经足以来模拟栈。我们只需要在每一次往队列中输入数据时,确保当前队列中的输出顺序和栈相同即可。同样我们使用图片来模拟一下过程。
1.输入1,这时队列为空,将1正常输入

clipboard.png

2.输入2,这时为了确保队列的输出顺序和栈相同,我需要将1输出并重新输入,这时可以把1看成一个新输入的值,所以将在2之后输出

clipboard.png

3.输入3,同上一步,在输入新加入的值后,将余下的值输出后重新输入一遍

clipboard.png

其实队列的最大特点就是可以维护原来的输入顺序,因此每次输出再重新输入的数据之间的顺序不会受到影响。

4.pop和push只需要输出或者读取队首的值即可

clipboard.png

class MyStack {

    /** Initialize your data structure here. */
    Queue<Integer> queue;
    public MyStack() {
        queue = new LinkedList<>();
    }
    
    /** Push element x onto stack. */
    public void push(int x) {
        int size = queue.size();
        queue.offer(x);
        while (size-- > 0) {
            queue.offer(queue.poll());
        }
        
    }
    
    /** Removes the element on top of the stack and returns that element. */
    public int pop() {
        return queue.poll();
    }
    
    /** Get the top element. */
    public int top() {
        return queue.peek();
    }
    
    /** Returns whether the stack is empty. */
    public boolean empty() {
        return queue.isEmpty();
    }
}

clipboard.png
想要了解更多开发技术,面试教程以及互联网公司内推,欢迎关注我的微信公众号!将会不定期的发放福利哦~


raledong
2.7k 声望2k 粉丝

心怀远方,负重前行