Likou-minimum stack (Java implementation)

Question content

Design a stack that supports push, pop, topoperations and can retrieve the smallest element in constant time.

  • push(x) - Push element x onto the stack.
  • pop() - removes the element at the top of the stack.
  • top() - Get the top element of the stack.
  • getMin() - retrieves the smallest element in the stack.

Example:

输入:
["MinStack","push","push","push","getMin","pop","top","getMin"]
[[],[-2],[0],[-3],[],[],[],[]]

输出:
[null,null,null,null,-3,null,0,-2]

解释:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin();   --> 返回 -3.
minStack.pop();
minStack.top();      --> 返回 0.
minStack.getMin();   --> 返回 -2.

hint:

  • pop, topand getMinoperations are always called on a non-empty stack.

Problem-solving ideas

When solving this problem, the idea adopted is to use an auxiliary stack to store the smallest value in the current stack. When adding the first element, the stack storing the minimum value must be empty, and the first element added at this time must also be the current minimum element, so the current element is pushed into the minimum stack. Next, when other elements are pushed onto the stack, they are compared with the top element of the stack that currently stores the minimum value. If the value of the element to be pushed onto the stack is less than the element on the top of the stack, the element is pushed into the auxiliary stack that stores the minimum value at the same time. In the same way, when an element is popped from the stack, it must be compared with the element that stores the minimum value. If the value of the element to be popped from the stack is equal to the top element of the current auxiliary stack, the value of the element in the auxiliary stack will be compared. The top elements of the stack are popped together.

problem solving code

class MinStack {
    
    
    Stack<Integer> stack;
    Stack<Integer> minStack;

    public MinStack() {
    
    
        // 在调用构造方法时创建两个栈
        stack = new Stack<>();
        // 创建辅助栈用来存储最小值
        minStack = new Stack<>();
    }
    
    public void push(int val) {
    
    
        // 在入栈时要注意如果当前元素为最小元素则额外将其添加到辅助栈中
        // 先将要入栈的元素与当前辅助栈中的元素进行比较
        if (minStack.isEmpty() || minStack.peek() >= val) {
    
    
            minStack.push(val);
        }
        stack.push(val);
    }
    
    public void pop() {
    
    
        // 在取出元素时先与辅助栈中的元素进行比较,如果值一致则一并出栈
        // 要使用equals进行比较
        if (stack.pop().equals(minStack.peek())) {
    
    
            minStack.pop();
        }
    }
    
    public int top() {
    
    
        // 返回栈的栈顶指针即可
        return stack.peek();
    }
    
    public int getMin() {
    
    
        // 直接返回最小栈的栈顶指针即可
        return minStack.peek();
    }
}

/**
 * Your MinStack object will be instantiated and called as such:
 * MinStack obj = new MinStack();
 * obj.push(val);
 * obj.pop();
 * int param_3 = obj.top();
 * int param_4 = obj.getMin();
 */

topic harvest

In this question, there are no obstacles in terms of ideas and code logic, but a problem occurred when comparing element values, resulting in an error in the answer. The problem is that when comparing Integertype data with type data in Java, methods should be used for comparison, but I initially used symbols for comparison, which caused an error. Record and summarize here, and record comparisons with methods to strengthen understanding and memory.Integerequals()====equals()

summary record

In Java, Integertypes are intpackaging classes for type data. Since JDK 1.5 has a new feature of automatic unboxing , when comparing Integertype data with type data , the type data will undergo automatic unboxing . process , so it is essentially equivalent to comparing two types of data, and there are the following two situations when comparing two types of data.intIntegerintInteger

  • When two type data are obtained not in new Integer()this way but in this way , the data value of the type is in the range of -128 to 127, because when the type data is used as a constant, the number in this range will Cache, so the comparison in this case is equivalent to comparing the same address . For numbers outside this range, it is equivalent to getting a new object.Integer num = 100;IntegerIntegerIntegernew Integer()
  • No matter what the situation is, as long as it is compared with the type of data new Integer()obtained in this way, it is equivalent to comparing two different objects, so they will not be the same.Integer

Therefore, equals should be used instead of '==' when judging equality between packaging types . Record it here as a warning!

Guess you like

Origin blog.csdn.net/qq_48455576/article/details/122738882