剑指offer——面试题21:包含 min 函数的栈
2017-10-29 11:28
357 查看
题目:定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数。
代码:
分析:
刚拿到这个问题,第一反应可能是,每压入一个数据,就将栈里面的数据进行排序,保证最小的元素位于栈顶,这样,就能够在 O(1)的情况下,得到最小的元素了。但是,这种方法显然改变了数据结构,不能保证最后压入栈的元素能够最先出栈,因为这个数据结构已经不是栈了。
那么,能不能在栈中添加一个成员变量,每当压入一个新元素时,如果这个新元素比当前最小的元素还要小,那么,就更新最小的元素。但是,如果面试官问你:如果当前最小的元素已经被弹出栈了,我们如何确定下一个最小的元素?分析到这里,我们明白了:仅仅添加一个成员变量来保存最小的变量,是不够的,我们需要构建一个辅助栈,把每次的最小的元素(之前的最小元素和新压入栈的元素的较小值)都压入辅助栈中。
下面详细分析下这个过程:
从表中我们可以看出,如果我们每次都把最小的元素压入辅助栈中,那么就能保证辅助栈中的元素一直是最小的元素。当最小的元素被从数据栈中弹出来的时候,同时弹出辅助栈的栈顶元素。此时,辅助栈新的栈顶的元素,就是下一个最小的元素了。
《剑指offer》中的代码比我上面写的好,好在加了断言 assert(),保证了程序的鲁棒性。代码如下:
#pragma once
#include <stack>
#include <assert.h>
template <typename T> class StackWithMin
{
public:
StackWithMin(void) {}
virtual ~StackWithMin(void) {}
T& top(void);
const T& top(void) const;
void push(const T& value);
void pop(void);
const T& min(void) const;
bool empty() const;
size_t size() const;
private:
std::stack<T> m_data; // 数据栈,存放栈的所有元素
std::stack<T> m_min; // 辅助栈,存放栈的最小元素
};
template <typename T> void StackWithMin<T>::push(const T& value)
{
// 把新元素添加到辅助栈
m_data.push(value);
// 当新元素比之前的最小元素小时,把新元素插入辅助栈里;
// 否则把之前的最小元素重复插入辅助栈里
if(m_min.size() == 0 || value < m_min.top())
m_min.push(value);
else
m_min.push(m_min.top());
}
template <typename T> void StackWithMin<T>::pop()
{
assert(m_data.size() > 0 && m_min.size() > 0);
m_data.pop();
m_min.pop();
}
template <typename T> const T& StackWithMin<T>::min() const
{
assert(m_data.size() > 0 && m_min.size() > 0);
return m_min.top();
}
template <typename T> T& StackWithMin<T>::top()
{
return m_data.top();
}
template <typename T> const T& StackWithMin<T>::top() const
{
return m_data.top();
}
template <typename T> bool StackWithMin<T>::empty() const
{
return m_data.empty();
}
template <typename T> size_t StackWithMin<T>::size() const
{
return m_data.size();
}
代码:
class Solution { public: void push(int value) { dataStack.push(value); if(minStack.empty() || minStack.top() > value) // 本题最重要的就是什么时候,将什么数据压入到两个栈中 { minStack.push(value); } else minStack.push(minStack.top()); } void pop() { minStack.pop(); dataStack.pop(); } int top() { return dataStack.top(); } int min() { return minStack.top(); } private: stack<int> dataStack; stack<int> minStack; };
分析:
刚拿到这个问题,第一反应可能是,每压入一个数据,就将栈里面的数据进行排序,保证最小的元素位于栈顶,这样,就能够在 O(1)的情况下,得到最小的元素了。但是,这种方法显然改变了数据结构,不能保证最后压入栈的元素能够最先出栈,因为这个数据结构已经不是栈了。
那么,能不能在栈中添加一个成员变量,每当压入一个新元素时,如果这个新元素比当前最小的元素还要小,那么,就更新最小的元素。但是,如果面试官问你:如果当前最小的元素已经被弹出栈了,我们如何确定下一个最小的元素?分析到这里,我们明白了:仅仅添加一个成员变量来保存最小的变量,是不够的,我们需要构建一个辅助栈,把每次的最小的元素(之前的最小元素和新压入栈的元素的较小值)都压入辅助栈中。
下面详细分析下这个过程:
从表中我们可以看出,如果我们每次都把最小的元素压入辅助栈中,那么就能保证辅助栈中的元素一直是最小的元素。当最小的元素被从数据栈中弹出来的时候,同时弹出辅助栈的栈顶元素。此时,辅助栈新的栈顶的元素,就是下一个最小的元素了。
《剑指offer》中的代码比我上面写的好,好在加了断言 assert(),保证了程序的鲁棒性。代码如下:
#pragma once
#include <stack>
#include <assert.h>
template <typename T> class StackWithMin
{
public:
StackWithMin(void) {}
virtual ~StackWithMin(void) {}
T& top(void);
const T& top(void) const;
void push(const T& value);
void pop(void);
const T& min(void) const;
bool empty() const;
size_t size() const;
private:
std::stack<T> m_data; // 数据栈,存放栈的所有元素
std::stack<T> m_min; // 辅助栈,存放栈的最小元素
};
template <typename T> void StackWithMin<T>::push(const T& value)
{
// 把新元素添加到辅助栈
m_data.push(value);
// 当新元素比之前的最小元素小时,把新元素插入辅助栈里;
// 否则把之前的最小元素重复插入辅助栈里
if(m_min.size() == 0 || value < m_min.top())
m_min.push(value);
else
m_min.push(m_min.top());
}
template <typename T> void StackWithMin<T>::pop()
{
assert(m_data.size() > 0 && m_min.size() > 0);
m_data.pop();
m_min.pop();
}
template <typename T> const T& StackWithMin<T>::min() const
{
assert(m_data.size() > 0 && m_min.size() > 0);
return m_min.top();
}
template <typename T> T& StackWithMin<T>::top()
{
return m_data.top();
}
template <typename T> const T& StackWithMin<T>::top() const
{
return m_data.top();
}
template <typename T> bool StackWithMin<T>::empty() const
{
return m_data.empty();
}
template <typename T> size_t StackWithMin<T>::size() const
{
return m_data.size();
}
相关文章推荐
- 剑指offer 面试题21 包含 min 函数的栈
- 【剑指Offer学习】【面试题21:包含min 函数的钱】
- 剑指Offer—20—包含 min 函数的栈
- 剑指offer 面试题21 包含min函数的栈 Java实现
- 面试题12 - 包含 min 函数的栈 【栈】
- 《剑指offer》(面试题21):包含min函数的栈
- 剑指offer面试题21之包含min函数的栈
- 剑指offer之面试题21:包含min函数的栈
- 微软面试题系列(二):设计包含 min 函数的栈
- 《剑指Offer》学习笔记--面试题21:包含min函数的栈
- 剑指Offer面试题21(Java版):包含min函数的栈
- 微软面试题解题笔记——包含min 函数的栈
- 面试题三:设计包含 min 函数的栈。
- 【剑指offer】面试题 30:包含 min 函数的栈
- 《剑指Offer》面试题21:包含min函数的栈
- 剑指offer——面试题21:包含min函数的栈
- 剑指offer——面试题21:包含min函数的栈
- 算法与数据结构面试题(2)-设计包含min 函数的栈
- 21 包含 min 函数的栈
- 剑指offer-面试题21:包含min函数的栈