【死磕算法·栈和队列】如何实时查询栈中最小值

题目大意:实现一个特殊的栈,在实现栈的基本功能的基础上,实现返回栈中最小元素的操作getmin()

要求:设计的栈类型可以使用现成的栈结构,其中 pop()、push()、getMin()操作的时间复杂度为O(1)

题目思路(涉及到栈操作):

方法一

1、设置两个同步操作的栈 stackData,stackMin。stackData进行正常栈操作,stackMin存储每一步操作后的最小值。

2、两个栈为空时,将元素直接压入栈stackData 和stackMin中。

3、当前入栈的值压入stackData中,若该值小于等于stackMin的栈顶值,即这个元素(记为x)入栈之后,stackData中的最小值应当是x,因此将x压入stackMin中。

4、当前入栈的值压入stackData中,若待入栈的值大于stackMin的栈顶值,不将该值加入stackMin栈中。

5、出栈时若stackData的栈顶元素和stackMin的栈顶元素相等,则两个栈都执行pop操作;若stackData的栈顶元素大于stackMin的栈顶元素,只对stackData执行pop操作。

注意在入栈时必须当前值小于等于stackMin的栈顶元素,而不仅仅是小于。

如果当前值只有小于stackMin的栈顶元素才可以入栈,如{3,3,3,3}顺序入栈,stackMin中的元素始终为3.执行一次pop操作后,因为是否从stackMin中弹出元素取决于要弹出的元素是不是和stackMin 的栈顶元素相等,在这个例子中stackMin弹出元素后为空,而此时stackData中元素为{3,3,3},不符合stackMin存储stackData中最小值的定义。

代码实现:

class Solution {
public:
    stack <int> stackData;
    stack<int> stackMin;
    void push(int value) {
        stackData.push(value);
        if(stackMin.size()==0)
            stackMin.push(value);
        else{
            if(stackMin.top()>value)
                 stackMin.push(value);
        }
    }
    void pop() {
        if(stackData.size()>0){
            if (stackData.top()==stackMin.top())
            {
                stackData.pop();
                stackMin.pop();
            }
            else
                stackData.pop();
        }
    }
    int top() {
        return stackData.top();
    }
    int min() {
        return stackMin.top();
    }
};

可以对此方法进行一下变动:

方法二:

1、仍设有stackData和stackMin

2、待入栈元素大于stackMin的栈顶元素时,stackMin将栈顶元素(当前最小值)重复压入。

3、弹出元素时stackData 和stackMin同步弹出。

代码实现:

class Solution {
public:
    stack <int> stackData;
    stack<int> stackMin;
    void push(int value) {
        stackData.push(value);
        if(stackMin.size()==0)
            stackMin.push(value);
        else{
            if(stackMin.top()>value)
                 stackMin.push(value);
            else
                stackMin.push(stackMin.top());
        }
    }
    void pop() {
        if(stackData.size()>0){
          
                stackData.pop();
                stackMin.pop();
          }
    }
    int top() {
        return stackData.top();
    }
    int min() {
        return stackMin.top();
    }
};

相比之下,第一种方法比第二种方法稍耗时间,但节省了空间;第二种方法比第一种方法多用了空间,但节省了时间。

猜你喜欢

转载自blog.csdn.net/gulaixiangjuejue/article/details/85036879