包含min函数的栈

定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。

示例:

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

思路:

用一个栈来保存push和pop的数。push和pop的时间复杂度不用多管,直接就符合题意。问题在于min函数。如果用一个变量x记录最小值,则可以每次都在O(1)的时间内执行min。但是如果pop的就是当前的最小值,再直接返回x就无法正确返回最小值。所以栈里存的数要跟最小值联系上。每次push和pop的时候去更新最小值。这时差值就非常适合。如果栈里保存的数就是每次push的数和最小值的差值,那么push和pop的时候,就可以正常执行,并且可以正确维护最小值

代码:

class MinStack {
private:
    //有加减乘除操作都有可能造成溢出,结果不对。所以用long long类型
    stack<long long> stk;
    long long minX = 0;
public:
    /** initialize your data structure here. */
    MinStack() {

    }
    //push差值,更新最小值
    void push(int x) {
        if(stk.empty()) {
            minX = x;
        }
        stk.push(x - minX);
        minX = minX < x ? minX: x;
    }
    //pop正常执行,有必要时,更新最小值
    void pop() {
        if(!stk.empty()) {
            if(stk.top() < 0) {
                minX = minX - stk.top();
            }
            stk.pop();
        }
    }
    //如果当前的差值大于0,那么返回最小值和栈顶的和,否则,直接返回最小值,因为此时最小值就是原始的x
    int top() {
        if (!stk.empty()) {
            if(stk.top() > 0) {
                return minX + stk.top();
            }
            else {
                return minX;
            }
        }
        return INT_MAX;
    }
    //直接返回最小值
    int min() {
        if(stk.empty()) {
            return INT_MAX;
        }
        return minX;
    }
};