Sword refers to offer—day 1. Use two stacks to implement the queue and the stack containing the min function

1. Implement a queue with two stacks

Source of this question: Likou

icon-default.png?t=MBR7Sword Pointer Offer 09. Using two stacks to implement a  queue - LeetCode https://leetcode.cn/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof/Description

Implement a queue with two stacks. The declaration of the queue is as follows, please implement its two functions appendTail and deleteHead to complete the function of inserting an integer at the tail of the queue and deleting an integer at the head of the queue respectively. (If there is no element in the queue, the deleteHead operation returns -1)

Example 1

Input:
["CQueue","appendTail","deleteHead","deleteHead","deleteHead"]
[[],[3],[],[],[]]
Output: [null,null,3,- 1,-1]

Example 2

输入:
["CQueue","deleteHead","appendTail","appendTail","deleteHead","deleteHead"]
[  [],[],[5],[2],[],[]  ]
输出:[null,-1,null,null,5,2]

Example interpretation :

  • CQueue is a constructor, which initializes the class, but does not add data to it, [ ] means no return value
  • appendTail adds elements at the end of the queue, no return value [ ]
  • deleteHead deletes the head element of the team, if there is no element in the team (example 2), it returns -1, if there is an element (example 1), it returns the deleted element

 problem solving ideas

Due to the first-in-first-out nature of the queue, it is necessary to ensure that the stacking sequence is the same as the stacking sequence when the last stacking operation is performed.

  • Push operation does not need to pay too much attention
  • The stack operation is the key

The specific process is as follows

  1. Prepare two stacks (s1 and s2), s1 is used to enter data, and s2 is used to output data
  2. Enter data into s1 without considering other
  3. When outputting data, first check whether there is any data in s2, if there is, you can directly record and output the top data of the stack
  4. If there is no data in s2, check s1, if there is no data in s1, return -1
  5. If there is data in s1, all the data in s1 will be popped out of the stack in turn, and pushed into s2 in turn . At this time, the later the elements that are pushed into the stack in s1, the closer to the bottom of the stack in s2, and the earlier the elements that are pushed into the stack, the closer they will be. at the top of the stack
  6. Then repeat step 3

Implementation code

class CQueue {
public:
    CQueue() {}
    
    void appendTail(int value) {  // 步骤2
        s1.push(value);
    }
    
    int deleteHead() {
        int ret;
        if(!s2.empty())   // 步骤3
        {
           ret = s2.top(); 
           s2.pop();
        }

        // no data in s2, check s1
        else                         // 步骤4
        {
            if(s1.empty())
            {
                return -1;  // if s1 is empty, there is no integer push ,return -1
            }

            // If there is data in s1,the  will be exited and all will enter s2
            while(!s1.empty())        // 步骤5
            {
                int tmp = s1.top();
                s2.push(tmp);
                s1.pop();
            }

            ret = s2.top();          // 步骤6
            s2.pop();
        }

        return ret;
    }
private:
    // 步骤1
    stack<int> s1; // s1 is uesd to input integer
    stack<int> s2; // s2 is used to output integer
};

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

 

2. The stack containing the min function

Topic Source: Leetcode

icon-default.png?t=MBR7Jianzhi Offer 30. A stack containing the min function - LeetCode https://leetcode.cn/problems/bao-han-minhan-shu-de-zhan-lcof/Description

To define the data structure of the stack, please implement a min function that can get the smallest element of the stack in this type. In this stack, the time complexity of calling min, push and pop is O(1)

example

MinStack minStack = new MinStack();
myStack.push(-2);
myStack.push(0);
myStack.push(-3);
myStack.min(); --> returns -3.
myStack.pop();
myStack.top(); --> 内容 0.
minStack.min(); --> returns -2.

problem solving ideas

For a stack, the pop and push operations are both O(1), so what this question examines is how to achieve the minimum value of O(1), the original stack needs to be traversed, and the time complexity is O(N), so the solution to the problem The idea is to use another stack to dynamically save the minimum value of the stack

We use two stacks in total, s1 is used to push data into the stack, and s2 is used to store the minimum value of the current stack. There are a few points to note

  • Every time it is pushed to the stack, it is checked whether this element is larger than the top element of s2. If it is, it means that the top of s2 still saves the smallest element in s1. At this time, this element is only pushed to s1, not into the stack. s2. For example, the stacking sequence of s1 is 2, 3, 1, then the stacking sequence of s2 is 2, 1
  • If the stacking order of s1 is 2, 1, 1, then two 1s need to be pushed into the stack in s2, because if only one 1 is pushed into the stack, then after s1 pop(), s2 will also pop(), at this time s1: 2 , 1 and s2: 2, does not match

The specific process is as follows

  1. Prepare two stacks (s1 and s2), s1 is used to enter data, and s2 is used to dynamically save the minimum value in s1
  2. When pushing to the stack, check the size of the pushed element and the top element of s2 (note that s2 is empty)
  3. If the stack is empty or the stacked element is less than or equal to the top element of s2, both s1 and s2 are pushed into the stack
  4. If the stacked element is greater than the top element of s2, only s1 will be loaded
  5. When popping the stack, if the top element of s1 is greater than (it can only be greater than or equal to) the top element of s2, only s1 will be popped
  6. If the top element of s1 stack is equal to the top element of s2 stack, then s1 and s2 are popped out of the stack at the same time
  7. The top of the stack of s2 keeps the minimum value of s1, so the time complexity is O(1)

Implementation code

class MinStack {
public:
    /** initialize your data structure here. */
    MinStack()  {}
     
    void push(int x) {                    // 步骤2
        // if s2 is empty or the entered value isn't greater than the top element in s2,record it
        if(s2.empty() || s2.top() >= x)   // 步骤3
        {
            s1.push(x);
            s2.push(x);
        }

        // if the entered value is greater than the top element in s2, don't push it to s2 
        else                               // 步骤4   
        {
            s1.push(x); 
        }
    }
    
    // be careful when pop an element,compare s1.top and s2.top firstly to check if it
    void pop() {                      
        if(s1.top() > s2.top()) // s1.top > s2.top, just pop s1  // 步骤5
        {
            s1.pop();
        }
        else                    // pop s1 and s2 both            // 步骤6
        {
            s1.pop();
            s2.pop();
        }
    }
    
    int top() {
        return s1.top();
    }
    
    int min() {                             // 步骤7
        return s2.top();
    }
 
private:                     // 步骤1
    stack<int> s1; // stack s1 is used store data
    stack<int> s2; // stack s2 is used to record the minimum element in s1
};

/**
 * Your MinStack object will be instantiated and called as such:
 * MinStack* obj = new MinStack();
 * obj->push(x);
 * obj->pop();
 * int param_3 = obj->top();
 * int param_4 = obj->min();
 */

Guess you like

Origin blog.csdn.net/weixin_58165485/article/details/128741179