Sword refers to Offer30-stack containing min function (monotonic stack)

Problem Description

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

Example:

MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.min();   --> 返回 -3.
minStack.pop();
minStack.top();      --> 返回 0.
minStack.min();   --> 返回 -2.

Problem-solving ideas:

The problem of monotonic stack can be started from the conventional thinking, and then dig out some of the nature of the problem.
Conventional thinking: the complexity of the push() and pop() functions of the ordinary stack is O(1); and the minimum value of the stack min() function Need to traverse the entire stack, the complexity is O(N) .
Difficulties of this question: Reduce the complexity of the min() function to O(1)O(1), which can be achieved by building a monotonic stack;
data stack A: Stack A is used to store all elements, ensuring that the push() function is pushed into the stack, and the stack is popped The pop() function, get the normal logic of the top() function on the top of the stack.
Monotonic stack B: Stack B stores all the elements in stack A in non-strictly descending order, then the smallest element in stack A always corresponds to the top element of stack B, that is, the min() function only needs to return the top element of stack B .
Therefore, only need to try to maintain the elements of stack B to maintain non-strict descending order (from the bottom of the stack to the top of the stack), and the O(1) complexity of the min() function can be realized.

push(x):
first push the element into stack A, if stack B is empty, just push it directly into stack B, otherwise it will be pushed only when the element is smaller (or equal) than the current stack top element In stack B. In this way, it can be guaranteed that the stack B decreases monotonically from the bottom of the stack to the top of the stack .

Doubtful point: why only the inserted element is pushed into stack B when it is smaller than the current element on the top of the stack .
Let us assume that the top element of stack B is our minimum value min, and this minimum value min is also located in stack A when the element x is inserted.
If x is larger than the top element of the stack, then there is no need to insert it into stack B. At this time, the minimum value of stack A is still min. Since the stack is last-in, first-out, x pops out of the stack before min, and is smaller if it is not inserted. Before the element, the smallest element in the stack can still be kept as min until min is popped. So
if x is smaller than the top element of the stack, then insert x into stack B. At this time, the minimum value of stack A is x. When x is popped, the element x in stack B will also be popped, and min becomes The minimum value of stack A.
The key point is that the "minimum values" in stack B are popped in the same order as these "minimum values" are popped in stack A.
pop():
First pop the top element of stack A. If the element is the top element of stack B, then the top element of stack B will also be popped.
min()
returns directly to the top element of stack B. .
top()
returns the top element of stack A.

Implementation code

class MinStack {
    
    
    public Stack<Integer> stack1;           //元素栈
    public Stack<Integer> stack2;           //单调栈
    /** initialize your data structure here. */
    public MinStack() {
    
    
        stack1=new Stack<Integer>();
        stack2=new Stack<Integer>();
    }
    
    public void push(int x) {
    
    
        stack1.push(x);     
        //只有栈2为空或者x比栈2的栈顶元素的值还要小(一定要包含等于)的时候,才会将x加入栈2中
        if(stack2.empty() || x<=stack2.peek()){
    
    
            stack2.push(x);
        }
    }
    
    public void pop() {
    
    
        int ele=stack1.pop();
        //当栈2不为空,且弹出的元素恰好等于栈2的栈顶元素值时,就把栈2的栈顶元素值也跟着弹出
        if(!stack2.empty() && ele==stack2.peek()){
    
    
           stack2.pop();
        }
    }
    
    public int top() {
    
    
        //直接返回栈1的栈顶元素值即可
        return stack1.peek();
    }
    
    public int min() {
    
    
        //直接返回栈2的栈顶元素值即可
        if(!stack2.empty()){
    
    
            return stack2.peek();
        }
        return 0;
    }
}

Guess you like

Origin blog.csdn.net/qq_39736597/article/details/113816319