如果没有min,该栈可以很轻松地构造出来,现在添加了一个min功能,首先想到的是在栈的数据结构里增加一个字段来标识栈中的最小元素,每次入栈的时候将待入栈的数与该最小元素比较,根据结果来做相应的替换,当仔细想一下之后,发现存在这样一种情况:在某一元素出栈之后,假设该元素为栈中的最小元素,那么标识栈中的最小元素的那个字段应该做何改变?而且再也无法正确找出该栈中的最小元素!
于是,为了记录栈的每一种状态,不可能通过一个字段就能实现,因此,构造一个辅助栈来记录,辅助栈的元素个数与主栈的元素个数相同,辅助栈的栈顶代表当前主栈中最小元素的位置(考虑到栈元素数据结构的复杂性,只记录位置可以节省空间)。
1.元素入栈之后,则可以先在辅助栈的栈顶找到入栈之前主栈中的最小元素,然后与入栈元素相比较
2.元素出栈的时候,只需要将主栈出栈和辅助栈出栈,因为只要当主栈和辅助栈的长度相同,辅助栈中的栈顶就代表了当前主栈中的最小元素的序号,这是一一对应的关系
3.min函数只需要根据辅助栈的栈顶得到最小元素的序号即可在O(1)时间内找到
template <typename T> class CStackWithMin
{
public:
private:
};
// get the last element of mutable stack
template <typename T> T& CStackWithMin<T>::top()
{
}
// get the last element of non-mutable stack
template <typename T> const T& CStackWithMin<T>::top() const
{
}
//将当前元素入栈
template <typename T> void CStackWithMin<T>::push(const T& value)
{
}
// 弹出栈中的最小元素
template <typename T> void CStackWithMin<T>::pop()
{
}
// 得到栈中的最小元素
template <typename T> const T& CStackWithMin<T>::min() const
{
}
可能有些朋友不明白为什么在出栈的时候只要将两个栈分别出栈即可,读者可以仔细分析一下,记住这样一条规律:只要主栈的长度和辅助栈的长度一样的时候,那么辅助栈的栈顶一定代表着主栈中最小元素的序号。个人认为这是一种变相的动态规划,每一个子结构的性质都满足这条规律,因此,我们只需要保证两个栈的长度相等即可在O(1)时间内找出最小元素,读者可以用下面的例子测试一下(转自何海涛博客)
举个例子演示上述代码的运行过程:
本文分析自何海涛博客
http://zhedahht.blog.163.com/blog/static/25411174200712895228171/