(剑指Offer)面试题21:包含min函数的栈

题目:

定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数。

在该栈中,调用min,push,pop的时间复杂度都是O(1)

思路:

1、除了原来的栈s,增加一个辅助栈s_min,用来保存每次进栈时的最小元素。

Push操作:

栈s:元素value直接进栈s;

栈s_min:判断s_min是否为空或者value是否小于s_min的栈顶元素,如果是,将value压入栈s_min,否则将s_min.top()压入栈s_min;

Pop操作:

栈s:s.pop();

栈s_min:s_min.pop();

Min操作:

return s_min.top();

2、思路1有个缺点就是如果每次进栈的元素都比原来最小元素大,那么栈中会重复记录相同的数字,这样大大浪费了存储空间。因此,我们可以只记录一个:

push操作:

栈s:元素value直接进栈s;

栈s_min:判断s_min是否为空或者value是否小于s_min的栈顶元素,如果是,将value压入栈s_min,否则不作为。

pop操作:

栈s:s.pop();

栈s_min:如果s.top()等于s_min.top(),则s_min.pop(),否则不作为;

Min操作:

return s_min.top();

缺点:当入栈存在重复元素时,在s_min的pop操作时会出现问题,这时需要在s_min中的每个最小值元素添加一个计数器,当计数器为0时,才进行pop操作。

代码:

这里只贴出思路1的实现代码。

template<typename T>
class StackWithMin{
public:
    void push(const T& value);
    void pop();
    const T& min() const;
private:
    stack<T> s;
    stack<T> s_min;
};

template<typename T>
void StackWithMin<T>::push(const T& value){
    s.push(value);
    if(s_min.empty() || value<s_min.top())
        s_min.push(value);
    else
        s_min.push(s_min.top());
}

template<typename T>
void StackWithMin<T>::pop(){
    assert(!s.empty() && !s.empty());
    s.pop();
    s_min.pop();
}

template<typename T>
const T& StackWithMin<T>::min() const{
    assert(!s.empty() && !s.empty());
    return s_min.top();
}

在线测试OJ:

http://www.nowcoder.com/books/coding-interviews/4c776177d2c04c2494f2555c9fcc1e49?rp=1

AC代码:

class Solution {
public:
    void push(int value) {
        s.push(value);
        if(s_min.empty() || value<s_min.top())
            s_min.push(value);
        else
            s_min.push(s_min.top());
    }
    void pop() {
        s.pop();
        s_min.pop();
    }
    int top() {
        return s.top();
    }
    int min() {
        return s_min.top();
    }
private:
    stack<int> s;
    stack<int> s_min;
};

  

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值