牛客网剑指Offer——包含min函数的栈

题目描述

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

方法一

考虑使用两个栈,一个数据栈(就是普通的栈),实现栈的push、pop等操作;另一个辅助栈用来存放每次栈操作时(包括入栈和出栈)栈中最小元素。

辅助栈的操作:栈顶元素为当前栈中的最小元素

  • 要获取当前栈中最小元素,只需要返回栈顶元素即可;
  • 每次执行push操作,检查push的元素与栈顶元素的大小关系。将较小的元素push到辅助栈中。
  • 当执行pop操作的时候,将辅助栈中的栈顶元素pop出去。

实例:


代码

class Solution {
public:
    stack<int> data;
    stack<int> minNum;
     
    void push(int value) {
        data.push(value);
        if( minNum.empty() )
            minNum.push(value);
        else
            minNum.push( minNum.top()<value?minNum.top():value );
    }
    void pop() {
//        assert( !data.empty() && !minNum.empty() );
        data.pop();
        minNum.pop();
    }
    int top() {
        return data.top();
    }
    int min() {
        return minNum.top();
    }
};
简单优化:对于辅助栈的操作,每次执行push操作时,检查push的元素是否小于或等于辅助栈栈顶元素。如果是,则也push该元素到辅助栈中。当执行pop操作的时候,检查pop的元素是否与当前最小值相等。如果相同,则需要将该元素从辅助栈中pop出去。其余情况对于辅助栈可以不做修改。

方法二

解法利用存储差值而不需要辅助栈,方法比较巧妙。该方法需要额外使用占用一个空间存储当前栈中的最小值,将最小值一直储存在栈顶。
  • 当需要push进一个新值value时,先将最小值pop出来,在栈中压入value与当前栈中最小元素的差值,然后比较value与当前栈中最小元素大小,将它们中间的较小值压入栈。
  • 执行min()函数时,直接返回栈顶元素即可。
  • 执行top()函数时,返回栈顶两个元素的和即可。
  • 执行pop()函数时,先pop出栈顶的两个值,这两个值分别是当前栈中最小值min和最后压入的元素与栈中最小值的差值diff,因为pop()函数需要把最后存入的值删除,所以只需要考虑pop后的最小值min是多少,并将其压入栈中。如果diff<0,则表示最后压入栈的元素是最小的元素,因此只需将min-diff压入栈中,min-diff就是当前元素弹出后,栈中剩下元素的最小值。而如果diff>=0且栈不为空,则表示当前值不是最小值,所以需要在栈中压入最小值min。
一个实例如下:
clear(): [ ] 
push(3): [3 3] 
push(4): [3 1 3] 
push(2): [3 1 -1 2] 
push(5): [3 1 -1 3 2] 
push(1): [3 1 -1 3 -1 1] 
push(1): [3 1 -1 3 -1 0 1] 
push(6): [3 1 -1 3 -1 0 5 1] 
push(7): [3 1 -1 3 -1 0 5 6 1]

min() --> 1; pop() --> 7: [3 1 -1 3 -1 0 5 1] 
min() --> 1; pop() --> 6: [3 1 -1 3 -1 0 1] 
min() --> 1; pop() --> 1: [3 1 -1 3 -1 1] 
min() --> 1; pop() --> 1: [3 1 -1 3 2] 
min() --> 2; pop() --> 5: [3 1 -1 2] 
min() --> 2; pop() --> 2: [3 1 3] 
min() --> 3; pop() --> 4: [3 3] 
min() --> 4; pop() --> 3: [ ]

代码

class Solution {
public:
    stack<int> data;
    void push(int value) {
        if( data.empty() )
        {
            data.push(value);
            data.push(value);
            return;
        }
        int min = data.top();
        data.pop();
        if( min <= value )
        {
            data.push(value-min);
            data.push(min);
            return;
        }
        else
        {
            data.push(value-min);
            data.push(value);
            return;
        }
        return;
    }
    void pop() {
        int min = data.top();
        data.pop();
        if( data.top() >= 0 )
        {
            data.pop();
            data.push(min);
            return;
        }
        else
        {
            int temp = data.top();
            data.pop();
            data.push(min-temp);
        }
        return;
    }
    int top() {
        int min = data.top();
        data.pop();
        int res = data.top()+min;
        data.push(min);
        return res;
    }
    int min() {
        return data.top();
    }
};

参考文献:

https://www.cnblogs.com/javawebsoa/archive/2013/05/21/3091727.html

https://blog.csdn.net/sgbfblog/article/details/7752878

猜你喜欢

转载自blog.csdn.net/qq_36132127/article/details/80187331