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, andis emptyoperations 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).
這道題讓我們用棧來實現隊列,之前我們做過一道相反的題目Implement Stack using Queues 用隊列來實現棧,是用隊列來實現棧。這道題顛倒了個順序,起始並沒有太大的區別,棧和隊列的核心不同點就是棧是先進后出,而隊列是先進先出,那么我們要用棧的先進后出的特性來模擬出隊列的先進先出。那么怎么做呢,其實很簡單,只要我們在插入元素的時候每次都都從前面插入即可,比如如果一個隊列是1,2,3,4,那么我們在棧中保存為4,3,2,1,那么返回棧頂元素1,也就是隊列的首元素,則問題迎刃而解。所以此題的難度是push函數,我們需要一個輔助棧tmp,把s的元素也逆着順序存入tmp中,此時加入新元素x,再把tmp中的元素存回來,這樣就是我們要的順序了,其他三個操作也就直接調用棧的操作即可,參見代碼如下:
解法一:
class MyQueue { public: /** Initialize your data structure here. */ MyQueue() {} /** Push element x to the back of queue. */ void push(int x) { stack<int> tmp; while (!st.empty()) { tmp.push(st.top()); st.pop(); } st.push(x); while (!tmp.empty()) { st.push(tmp.top()); tmp.pop(); } } /** Removes the element from in front of queue and returns that element. */ int pop() { int val = st.top(); st.pop(); return val; } /** Get the front element. */ int peek() { return st.top(); } /** Returns whether the queue is empty. */ bool empty() { return st.empty(); } private: stack<int> st; };
上面那個解法雖然簡單,但是效率不高,因為每次在push的時候,都要翻轉兩邊棧,下面這個方法使用了兩個棧_new和_old,其中新進棧的都先緩存在_new中,入股要pop和peek的時候,才將_new中所有元素移到_old中操作,提高了效率,代碼如下:
解法二:
class MyQueue { public: /** Initialize your data structure here. */ MyQueue() {} /** Push element x to the back of queue. */ void push(int x) { _new.push(x); } /** Removes the element from in front of queue and returns that element. */ int pop() { shiftStack(); int val = _old.top(); _old.pop(); return val; } /** Get the front element. */ int peek() { shiftStack(); return _old.top(); } /** Returns whether the queue is empty. */ bool empty() { return _old.empty() && _new.empty(); } void shiftStack() { if (!_old.empty()) return; while (!_new.empty()) { _old.push(_new.top()); _new.pop(); } } private: stack<int> _old, _new; };
類似題目:
參考資料:
https://leetcode.com/problems/implement-queue-using-stacks/
