Существует более креативное решение без использования вспомогательного стека.
Предположим, что мы собираемся поместить число значение в стек с минимальным числом min . Если значение больше или равно мин , оно помещается непосредственно в стек данных. Если оно меньше мин , мы нажимаем 2 ** значение * - мин и обновляем мин как значение , так как новый минимум номер выдвинут.
Как насчет поп? Мы извлекаем его напрямую, если вершина стека данных (она обозначается как top ) больше или равна min . В противном случае число top не является действительным введенным числом. Действительное введенное число сохраняется как min . После того, как текущий минимальный номер вытолкнут, нам нужно восстановить предыдущий минимальный номер, который составляет 2 ** мин * - top .
Теперь давайте продемонстрируем правильность этого решения. Когда значение больше или равно мин , оно помещается в стек данных напрямую без обновления мин . Следовательно, когда мы обнаруживаем, что вершина стека данных больше или равна min , мы можем получить всплывающее окно без обновления min . Однако, если мы находим значение меньше, чем мин , мы нажимаем 2 значение * - мин . Следует отметить, что значение 2 * - min меньше value . Затем мы обновляем текущее значение мин как значение . Поэтому новая вершина стека данных ( top ) меньше текущей min . Следовательно, когда мы находим, что вершина стека данных меньше мин , реальная вершина (действительное нажатое число значение ) сохраняется в мин . После того, как мы вытолкнули вершину стека данных, мы должны восстановить предыдущее минимальное число. Поскольку top = 2 ** значение * -предыдущее min и значение является текущим min , предыдущее min равно 2 * текущий мин - топ .
Пример кода C ++ показан ниже:
template <typename T> class StackWithMin {
public:
StackWithMin(void) {}
virtual ~StackWithMin(void) {}
T& top(void);
void push(const T& value);
void pop(void);
const T& min(void) const;
private:
std::stack<T> m_data; // data stack, to store numbers
T m_min; // minimum number
};
template <typename T> void StackWithMin<T>::push(const T& value) {
if(m_data.size() == 0) {
m_data.push(value);
m_min = value;
}
else if(value >= m_min) {
m_data.push(value);
}
else {
m_data.push(2 * value - m_min);
m_min = value;
}
}
template <typename T> void StackWithMin<T>::pop() {
assert(m_data.size() > 0);
if(m_data.top() < m_min)
m_min = 2 * m_min - m_data.top();
m_data.pop();
}
template <typename T> const T& StackWithMin<T>::min() const {
assert(m_data.size() > 0);
return m_min;
}
template <typename T> T& StackWithMin<T>::top() {
T top = m_data.top();
if(top < m_min)
top = m_min;
return top;
}
Это решение заимствовано из моего блога и моей книги " Интервью по кодированию: вопросы, анализ и решения ".