Sword finger Offer 09. Queue with two stacks

Posted by Mardoxx on Fri, 19 Nov 2021 20:09:11 +0100

Sword finger Offer 09. Queue with two stacks

Title Description:
Implement a queue with two stacks. The declaration of the queue is as follows. Please implement its two functions appendTail and deleteHead to insert integers at the end of the queue and delete integers at the head of the queue respectively. (if there are no elements in the queue, the deleteHead operation returns - 1)

My solution is also the stupidest solution:
Consider using two stacks to implement a queue. The stack is characterized by first in first out, and the queue is characterized by first in first out. It is relatively simple to add the tail of the queue and add it directly to the stack. The most troublesome thing is how to obtain the first element of the queue, because when adding elements to the stack, the front elements are at the bottom of the stack. When obtaining the first element of the queue, you need to pop up all the above elements.
My solution is, and it should be the solution of many people.

  1. Set two stacks, input and output. Input is used to add the tail element. Just add it directly.
  2. Output is used to obtain the first element of the queue. First pop up the elements in the input stack one by one and then press them into the output. In this way, the reverse order of the input elements is realized, so that the top element of the output stack becomes the bottom element of the input stack, that is, the element order of the queue is obtained.
  3. Then pop up the elements in the output one by one and press them into the input. In this way, the element order of input from the bottom of the stack to the top of the stack is the element order after the first element of the queue is deleted. (actually, there's no need to do this again, Abba, Abba, ABBA).
#include<stack>
#include<iostream>
using namespace std;

class CQueue {
private:
    stack<int> input;
    stack<int> output;

public:
    CQueue() {
    
    }
    
    void appendTail(int value) {
        input.push(value);
    }
    
    int deleteHead() {
        if(input.empty()){
            return -1;
        }
        else{
            int top;
            while (!input.empty())
            {
                output.push(input.top());
                input.pop();
            }
            top = output.top();
            output.pop();
            while (!output.empty())
            {
                input.push(output.top());
                output.pop();
            }
            return top;
        }
    }
};

/**
 * Your CQueue object will be instantiated and called as such:
 * CQueue* obj = new CQueue();
 * obj->appendTail(value);
 * int param_2 = obj->deleteHead();
 */

int main(){
    CQueue *obj = new CQueue();
    cout << obj->deleteHead();
    obj->appendTail(5);
    obj->appendTail(2);
    cout << obj->deleteHead();
    cout << obj->deleteHead();
    return 0;
}

Run time:

After that, I thought it was not very good. After thinking for a long time, I still read the official answer.
In fact, this is very simple. Step 3 above is completely unnecessary. During the first deletion operation, adding the elements in the input stack to the output realizes the separation of the end of the queue and the head of the queue. As long as there are elements in the output, you can directly obtain the top of the stack element of the output, that is, the head of the queue. Only when the output is empty, Then add the elements in the input to the output again according to the second step above to obtain a new team head element. Only return - 1 when both output and input are empty.

#include<stack>
#include<iostream>
using namespace std;

class CQueue {
private:
    stack<int> input;
    stack<int> output;

public:
    CQueue() {
    
    }
    
    void appendTail(int value) {
        input.push(value);
    }
    
    int deleteHead() {
        if(!output.empty()){         //If the output is not empty, just pop up the top element of the stack directly
            int top = output.top();
            output.pop();
            return top;
        }
        if (input.empty()) {  
            return -1;               //If the input is empty at this step, the output is also empty, that is, the queue is empty
        }
        while (!input.empty())       //From the above operation to this, it shows that output is empty and input is not empty. Add the elements in input to input
        {
            output.push(input.top());
            input.pop();
        }
        int top = output.top();       //Then output the team head element
        output.pop();
        return top;
    }
};

/**
 * Your CQueue object will be instantiated and called as such:
 * CQueue* obj = new CQueue();
 * obj->appendTail(value);
 * int param_2 = obj->deleteHead();
 */

int main(){
    CQueue *obj = new CQueue();
    cout << obj->deleteHead();
    obj->appendTail(5);
    obj->appendTail(2);
    cout << obj->deleteHead();
    cout << obj->deleteHead();
    return 0;
}

Topics: C++ Algorithm data structure leetcode