1. 程式人生 > >劍指offer面試題9:用兩個棧實現佇列(兩個佇列模擬棧)

劍指offer面試題9:用兩個棧實現佇列(兩個佇列模擬棧)

 題目描述:

用兩個棧來實現一個佇列,完成佇列的Push和Pop操作。 佇列中的元素為int型別。

思路一:有點死腦筋,每次pop後都預設下次是push操作,,,,。233主要是由於沒把握好兩個棧模擬時入隊和出隊的時機。考慮stack1和stack2的大小和入隊出隊的關係即可改進了

思路二:改進版(避免了預設下次是push操作導致的多餘的push和pop操作)

stack2模擬出隊,stack1模擬入隊,
1.(出隊)只要stack1還有元素,那麼出隊的應該是stack1的棧底元素,此時應該把stack1的元素出棧到stack2中,
2.(入隊)因為要保證入隊的順序元素之間的元素正確,那麼入棧時,stack2應該保持空,如多stack2非空那麼stack2的元素應該出現在stack1的中

思路三:思路二的進一步提升?,,,劍指offer(版)
 

class Solution1
{
public:
    void push(int node) {
        stack1.push(node);
    }

    int pop() {
       while(!stack1.empty()){
            stack2.push(stack1.top());
            stack1.pop();
        }
        int ans=stack2.top();
        stack2.pop();
        while(!stack2.empty()){
            int top=stack2.top();
            stack1.push(top);
            stack2.pop();
        }
        return ans;
    }

private:
    stack<int> stack1;
    stack<int> stack2;
};
/*模擬佇列:佇列(先進先出),棧(先進後出),為了讓棧模擬先進先出,即要能夠將棧底元素pop出,保持其他元素的順序,於是利用兩個棧來回倒即可
1.首先借助stack1完成佇列的入隊操作,
此時如果要出隊,那麼應該是stack1的棧底元素,但是棧的出棧順序是從頂部出棧的(先進後出),
2.藉助stack2將stack1的所有元素出棧到stack2中,那麼stack1出棧完後,stack2的棧頂元素即是所想要的佇列的出隊元素,此時將stack2做pop()操作即可
3.出隊完成後此時stack2的棧可能非空,為了下次出棧準備,把stack2的元素全部出棧到stack1中,這樣相當於把stack1的棧底元素pop()出,即模擬了先進先出;
*/
class Solution2
{
public:
    void push(int node) {
        while(!stack2.empty()){
            stack1.push(stack2.top());
            stack2.pop();
         }
        stack1.push(node);
    }
    int pop() {
        while(!stack1.empty()){
            stack2.push(stack1.top());
            stack1.pop();
        }
        int result=stack2.top();
        stack2.pop();
        return result;
    }

private:
    stack<int> stack1;
    stack<int> stack2;
};
/*stack2模擬出隊,stack1模擬入隊,
1.(出隊)只要stack1還有元素,那麼出隊的應該是stack1的棧底元素,此時應該把stack1的元素出棧到stack2中,
2.(入隊)因為要保證入隊的順序元素之間的元素正確,那麼入棧時,stack2應該保持空,如多stack2非空那麼stack2的元素應該出現在stack1的中*/

class Solution3
{
public:
    void push(int node) {
       stack1.push(node);
    }
    int pop() {
        if(stack2.empty()){
            while(!stack1.empty()){
                stack2.push(stack1.top());
                stack1.pop();
            }
        }
        if(stack2.size() == 0)
        throw new exception("queue is empty");
        int result=stack2.top();
        stack2.pop();
        return result;
         
    }
private:
    stack<int> stack1;
    stack<int> stack2;
};

劍指offer版 

template<typename T> void CQueue<T>::appendTail(const T& element)
{
    stack1.push(element);
} 

template<typename T> T CQueue<T>::deleteHead()
{
    if(stack2.size()<= 0)
    {
        while(stack1.size()>0)
        {
            T& data = stack1.top();
            stack1.pop();
            stack2.push(data);
        }
    }

    if(stack2.size() == 0)
        throw new exception("queue is empty");

    T head = stack2.top();
    stack2.pop();

    return head;
}
class Solution4{//佇列模擬棧
public:
    void push(int node){
        queue1.push(node);
    }
    int pop(){
        if(queue1.size()==0&&queue2.size()==0){
            throw runtime_error("queque is empty");
        }
        if(queue1.size()==0&&queue2.size()!=0){
            while(queue2.size()>1){
                queue1.push(queue2.front());
                queue2.pop();
            }
            int ans=queue2.front();
            queue2.pop();
            return ans;
        }
        while(queue1.size()>1){
            queue2.push(queue1.front());
            queue1.pop();
        }
        if(queue1.size()==1){//這裡判斷可以不需要
            int ans=queue1.front();
            queue1.pop();
            return ans;
        }

    }
private:
    queue<int> queue1;
    queue<int> queue2;
};