LeetCode:用栈实现队列

486 阅读1分钟

一、题目描述

二、思路分析

2.1 分析

首先先回忆一下队列的特点是先进先出,而栈是先进后出。因此我们想到出队的操作就是把栈底元素出栈,查看队首元素就是查看栈底元素,入队就是入栈操作。现在我们的问题是如何拿到栈底元素,想一想。定义两个栈就好了。一个栈 inStack 用来存放入队元素,另外一个栈 outStack 专门存放 inStack 出栈的元素。当我们入队的时候,将元素存入 inStack 中,出栈的话将 inStack 元素统统移到 outStack 中,此时 outStack 的栈顶元素就是我们要的出队元素啦。待 outStack 栈顶元素出栈以后(注意一下保留 outStack 出栈的队首元素),再将其栈内的元素移入 inStack 中。查看队首元素也是一样的思路,只不过不用移除而已。至于队列是否为空,我们只需要判断 inStack 就好了。
还有优化的空间。将 inStack 的元素全部放入 outStack, 并且移除或者查看队首元素后,不必将 outStack 元素再次放回 inStack 中。此时如果要查看或者移除队首元素,只需要看看 outStack 是否为空,不为空,返回 outStack 栈顶元素就好了。outStack 为空的话将 inStack 的元素移入 outStack 中。此时队列为空的条件就是两个栈都为空的情况

2.2 图解

三、题解

class MyQueue {
		// 存放入队元素
        private Stack<Integer> inStack = new Stack<>();
        // 存放出队元素
        private Stack<Integer> outStack = new Stack<>();

        /** Initialize your data structure here. */
        public MyQueue() {

        }

        /** Push element x to the back of queue. */
        public void push(int x) {
            inStack.push(x);
        }

        /** Removes the element from in front of queue and returns that element. */
        public int pop() {
        	// 将 inStack 存放到 outStack 中去
            while (!inStack.isEmpty()) {
                outStack.push(inStack.pop());
            }
            // 保存 outStack 当前栈顶元素,即为队首元素
            int ret = outStack.pop();
			// 将 outStack 的元素移回 inStack 中
            while (!outStack.isEmpty()) {
                inStack.push(outStack.pop());
            }
            return ret;
        }

        /** Get the front element. */
        public int peek() {
            while (!inStack.isEmpty()) {
                outStack.push(inStack.pop());
            }
            int ret = outStack.peek();

            while (!outStack.isEmpty()) {
                inStack.push(outStack.pop());
            }
            return ret;
        }

        /** Returns whether the queue is empty. */
        public boolean empty() {
        	// 返回 inStack 是否为空
            return inStack.isEmpty();
        }
}

/**
 * Your MyQueue object will be instantiated and called as such:
 * MyQueue obj = new MyQueue();
 * obj.push(x);
 * int param_2 = obj.pop();
 * int param_3 = obj.peek();
 * boolean param_4 = obj.empty();
 */
  • 优化后
class MyQueue {
        private Stack<Integer> inStack = new Stack<>();
        private Stack<Integer> outStack = new Stack<>();
        
        public MyQueue() {

        }

        public void push(int x) {
            inStack.push(x);
        }
        
        public int pop() {
            if (outStack.isEmpty()) {
                while (!inStack.isEmpty()) {
                    outStack.push(inStack.pop());
                }
            }
            return  outStack.pop();
        }

        public int peek() {
            if (outStack.isEmpty()) {
                while (!inStack.isEmpty()) {
                    outStack.push(inStack.pop());
                }
            }
            return  outStack.peek();
        }

        public boolean empty() {
            return inStack.isEmpty()  && outStack.isEmpty();
        }
}