โญ Introduction to algorithm โญ Stack and queue simple 02 -- LeetCode 225. Implement stack with queue

1, Title

1. Title Description

    please use only two queues to implement a last in first out (LIFO) stack, and support all four operations of ordinary stack (push, top, pop and empty). Implement MyStack class:
   void push(int x): push element x into the top of the stack.
   int pop(): removes and returns the top of stack element.
   int top(): returns the stack top element.
   boolean empty(): returns true if the stack is empty; Otherwise, false is returned.
Note: you can only use the basic operations of the queue -- that is, push to back, peek/pop from front, size, and is empty. The language used may not support queues. You can use list or deque to simulate a queue, as long as it is a standard queue operation.
   sample input: ["MyStack", "push", "push", "top", "pop", "empty"] [[], [1], [2], [], [], [], []]
   sample output: [null, null, null, 2, 2, false]

2. Basic framework

  • The basic framework code given in the C language version is as follows:


typedef struct {

} MyStack;

/** Initialize your data structure here. */

MyStack* myStackCreate() {

}

/** Push element x onto stack. */
void myStackPush(MyStack* obj, int x) {

}

/** Removes the element on top of the stack and returns that element. */
int myStackPop(MyStack* obj) {

}

/** Get the top element. */
int myStackTop(MyStack* obj) {

}

/** Returns whether the stack is empty. */
bool myStackEmpty(MyStack* obj) {

}

void myStackFree(MyStack* obj) {

}

/**
 * Your MyStack struct will be instantiated and called as such:
 * MyStack* obj = myStackCreate();
 * myStackPush(obj, x);
 
 * int param_2 = myStackPop(obj);
 
 * int param_3 = myStackTop(obj);
 
 * bool param_4 = myStackEmpty(obj);
 
 * myStackFree(obj);
*/

3. Original question link

( 1 ) (1) (1) LeetCode 225. Implement stack with queue

2, Problem solving Report

1. Train of thought analysis

  prepare two queues to simulate a stack: master queue and slave queue. The slave queue must be empty after each queue entry or exit operation.

Queue operation

  • Queue the elements to the slave queue, and then queue the elements of the main queue one by one to the slave queue. Then exchange the master-slave queue (the exchange process needs to do O ( 1 ) O(1) O(1)).

Out of line operation

  • After the operation is completed, the slave queue must be empty, so the outgoing queue must be listed from the master queue.
  • Here, the master-slave queue can be defined as an array of two queue elements, so that the exchange queue only needs to exchange subscripts.

2. Time complexity

  • Each queueing operation needs to use all elements in the queue, if any n n n queue operations with time complexity of O ( n 2 ) O(n^2) O(n2).

3. Code explanation

/**************************** Sequence table implementation queue****************************/
#define DataType int
#define maxn 100005

struct Queue {
    DataType data[maxn];
    int head, tail;
};

void QueueClear(struct Queue* que) {
    que->head = que->tail = 0;
}
void QueueEnqueue(struct Queue *que, DataType dt) {
    que->data[ que->tail++ ] = dt;
}
void QueueDequeue(struct Queue* que) {
    ++que->head;
}

DataType QueueGetFront(struct Queue* que) {
    return que->data[ que->head ];
}
int QueueGetSize(struct Queue* que) {
    return que->tail - que->head;
}
int QueueIsEmpty(struct Queue* que) {
    return !QueueGetSize(que);
}

/**************************** Sequence table implementation queue****************************/
typedef struct {
    struct Queue q[2];
    int idx;
} MyStack;

/** Initialize your data structure here. */
MyStack* myStackCreate() {
    MyStack *stk = (MyStack *) malloc ( sizeof(MyStack) );
    QueueClear( &stk->q[0] );
    QueueClear( &stk->q[1] );
    stk->idx = 0;
    return stk;
}

/** Push element x onto stack. */
void myStackPush(MyStack* obj, int x) {
    struct Queue *masterQ = &obj->q[obj->idx];            // (1) 
    struct Queue *slaverQ = &obj->q[obj->idx^1];          // (2) 
    QueueEnqueue( slaverQ, x );                           // (3) 
    while( !QueueIsEmpty(masterQ) ) {                     // (4) 
        QueueEnqueue( slaverQ, QueueGetFront(masterQ) );
        QueueDequeue( masterQ );
    }
    obj->idx ^= 1;                                        // (5) 

}

/** Removes the element on top of the stack and returns that element. */
int myStackPop(MyStack* obj) {
    struct Queue *masterQ = &obj->q[obj->idx];            // (6) 
    int pop = QueueGetFront(masterQ);                     // (7) 
    QueueDequeue(masterQ);
    return pop;
}

/** Get the top element. */
int myStackTop(MyStack* obj) {
    struct Queue *masterQ = &obj->q[obj->idx];
    return QueueGetFront(masterQ);
}

/** Returns whether the stack is empty. */
bool myStackEmpty(MyStack* obj) {
    struct Queue *masterQ = &obj->q[obj->idx];
    return QueueIsEmpty(masterQ);
}

void myStackFree(MyStack* obj) {
    free(obj);
}

/**
 * Your MyStack struct will be instantiated and called as such:
 * MyStack* obj = myStackCreate();
 * myStackPush(obj, x);
 
 * int param_2 = myStackPop(obj);
 
 * int param_3 = myStackTop(obj);
 
 * bool param_4 = myStackEmpty(obj);
 
 * myStackFree(obj);
*/
  • ( 1 ) (1) (1) Main queue pointer;
  • ( 2 ) (2) (2) Pointer from queue;
  • ( 3 ) (3) (3) First, insert the element into the slave queue;
  • ( 4 ) (4) (4) Then take out the elements of the main queue one by one and put them into the slave queue;
  • ( 5 ) (5) (5) Subscript exchange of master-slave queue;
  • ( 6 ) (6) (6) The main line must have elements;
  • ( 7 ) (7) (7) The head of the main line is the top of the stack we want to simulate;

3, Little knowledge of this topic

   rolling queue is actually the exchange of pointers between two queues, so the rolling process is O ( 1 ) O(1) O(1).

4, Instructions for group addition

    I believe most of the people who read my article are "college students", and those who can go to college are "elites", so we naturally want to "keep improving". If you are still a "freshman", then it's great. You have a lot of time. Of course, you can choose to "brush drama". However, if you "learn algorithms well", you will naturally "not be in the same breath" three years later.
   here, I sorted out the classification of "dozens of basic algorithms" and click to open:

๐ŸŒŒ Introduction to Algorithms ๐ŸŒŒ
  if the link is blocked or there is a permission problem, you can talk to the author in private.

  list of general problem sets:





  in order to make this interesting and "take care of beginners", the current topic only opens the simplest algorithm "enumeration series" (including linear enumeration, double pointer, prefix sum, binary enumeration and ternary enumeration). When half of the members brush the "enumeration series" After all the questions, the next chapter will be opened. When all the questions are finished and you are still in the group, you will become a member of the expert group of "writing algorithms in the dead of night".
  don't underestimate this expert group. In three years, you will be beyond the reach of others. If you want to join, you can contact me. Considering that everyone is a student and has no "main source of income", you "won't ask for anything" on your way to become God.
   ๐Ÿ”ฅ Contact the author, or scan the QR code of the author's home page and add a group to join the list of questions ๐Ÿ”ฅ

๐Ÿ”ฅ Let the world have no difficult algorithms ๐Ÿ”ฅ
C language free animation tutorial, punch in with me! ๐ŸŒž Daylight science C language ๐ŸŒž
Entry level C language real topic summary ๐Ÿงก 100 cases of introduction to C language ๐Ÿงก
Several dynamic graphs learn a data structure ๐ŸŒณ Drawing data structure ๐ŸŒณ
Group learning and group growth ๐ŸŒŒ Introduction to Algorithms ๐ŸŒŒ
Gold Classic graphic course for competitors ๐Ÿ’œ Writing algorithm in the dead of night ๐Ÿ’œ

Tags: C++ Algorithm data structure leetcode

Posted on Wed, 22 Sep 2021 09:29:37 -0400 by jariizumi