Leetcode algorithm solution series - minimum stack

Posted by ppera on Thu, 20 Jan 2022 19:26:24 +0100

This topic aims to share some interesting or valuable topics found in the process of brushing Leecode. [of course, the answer is based on js].

Topic related

  • Original title address
  • Title 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).

    MinStack minStack = new MinStack();
    minStack.push(-2);
    minStack.push(0);
    minStack.push(-3);
    minStack.min();   --> return -3.
    minStack.pop();
    minStack.top();   --> Return 0.
    minStack.min();   --> return -2.
    
    // The problem solving framework is as follows
    var MinStack = function() {};
    MinStack.prototype.push = function(x) {};
    MinStack.prototype.pop = function() {};
    MinStack.prototype.top = function() {};
    MinStack.prototype.min = function() {};
    
    // Actual call example 
    // var obj = new MinStack()
    // obj.push(x)

Train of thought analysis

  • First of all, let's take a rough look at the implementation of push and pop methods, which are relatively simple and can be implemented with the native methods of js array;
  • Secondly, the top method is simple as long as it returns the top element of the stack, that is, the last element of the array;
  • Then, the min method needs to obtain the minimum value, and the time complexity is O(1), which means that we can't traverse the array in the min method, and we must find a way to save it in advance; Moreover, in the push and pop processes, the saved minimum value needs to be updated.

So here we know that the core difficulty of this problem is how to save the minimum value of the current data stack

It is noted here that the title design requires the design of a stack structure, which means that data can only be accessed in one way, which is a key premise.

Next, take a step-by-step look at the example steps of the problem setting (take a serious look, otherwise it will pass at a whiz!):

  1. Initially, the data stack is empty. First -2 enter the stack. At this time:

    Data stack[-2]  // At this time, the minimum element value in the stack is - 2
  2. Then, when 0 is stacked, at this time:

    Data stack[-2, 0] // If 0 is greater than the existing minimum value of - 2, the minimum value is still - 2,

    Here is a key point. In the current state, the method of element out of the stack can only be 0 first and then - 2, that is, before - 2 out of the stack, the minimum value of elements in the stack is always - 2. Hearing this, do you have a sudden in your mind?!!!.

  3. Don't worry, continue to stack -3, at this time:

    The elements in the stack are[-2,0,-3]// The minimum value should be updated to - 3,

    Similarly, when - 3 is not out of the stack, the minimum value in the stack is - 3; When - 3 is out of the stack, the minimum value in the stack should be the previous minimum value - 2;

Then the solution will surface!!!

We only need to maintain another monotonically decreasing stack and always store only elements smaller than the minimum value in the current stack!

(I know some students still don't understand it when they see it here. It doesn't matter.) let's still give an example:

// The initial state is as follows
 Data stack  [-2];
Minimum stack [-2];

// -2 after entering the stack
 Data stack  [-2];
Minimum stack [-2];

// Since 0 is larger than - 2 after 0 is put into the stack, the minimum stack does not save - 2
 Data stack  [-2, 0];
Minimum stack [-2];

// -After 3 is put on the stack, - 3 is smaller than - 2, so the minimum value stack saves - 3
 Data stack  [-2, 0, -3];
Minimum stack [-2, -3];

// -3. When the stack is out, compare whether the out stack elements are the top elements of the [minimum value stack]. If yes, they are out of the stack together;
Data stack  [-2, 0];
Minimum stack [-2];

It can be seen from here that the minimum stack always maintains a monotonically decreasing array, and the top element of the stack (the last element of the array) always represents the minimum value of the current data stack.

Complete code

After understanding the core content above, the code is not difficult to write. Finally, paste the completed code:

var MinStack = function() {
    this.dataStack = [];
    this.minStack = [];
};

MinStack.prototype.push = function(x) {
    this.dataStack.push(x);
    const len =  this.minStack.length;
    if(len === 0 || x <= this.minStack[len-1]){
        this.minStack.push(x);
    }
};

MinStack.prototype.pop = function() {
   const last = this.dataStack.pop();
   const len =  this.minStack.length;
   if(last === this.minStack[len-1]){
       this.minStack.pop();
   }
};

MinStack.prototype.top = function() {
    const len = this.dataStack.length;
    return len > 0 ? this.dataStack[len - 1] : null;
};

MinStack.prototype.min = function() {
    const len =  this.minStack.length;
    return this.minStack[len-1];
};

A simple problem has been solved again!

Topics: Javascript Algorithm leetcode