C'è una soluzione più creativa senza utilizzare uno stack ausiliario.
Supponendo che stiamo per spingere un valore numerico in una pila con numero minimo min. Se il valore è maggiore o uguale allo min, viene inserito direttamente nello stack di dati. Se è inferiore a min, spingiamo 2 * valore - min, e modificare min come valore poiché un nuovo numero minimo viene spinto.
Che ne dici di pop?Lo inseriamo direttamente se la parte superiore dello stack di dati (indicata come top) è maggiore o uguale a min. Altrimenti il numero top non è il vero numero spinto. Il numero reale inserito viene memorizzato come min. Dopo che il numero minimo corrente è spuntato, dobbiamo ripristinare il numero minimo precedente, che è 2 * min - * top *.
Ora dimostriamo la sua correttezza di questa soluzione. Quando il valore è uguale o uguale a min, viene inserito direttamente nello stack di dati senza aggiornare min. Pertanto, quando scopriamo che la parte superiore dello stack di dati è maggiore o uguale a min, possiamo eseguire il pop direttamente senza aggiornare min. Tuttavia, se troviamo il valore è inferiore a min, si preme 2 * valore - * min *. Dovremmo notare che il valore 2 * - * min * è inferiore a valore. Quindi aggiorniamo l'attuale min come valore. Pertanto, la nuova parte superiore dello stack di dati (top) è inferiore all'attuale min. Pertanto, quando scopriamo che la parte superiore dello stack di dati è inferiore a min, il valore reale più alto (numero reale spinto valore) viene memorizzato in min. Dopo aver popolato la parte superiore dello stack di dati, dobbiamo ripristinare il numero minimo precedente. Poiché superiore = valore 2 * -precedente min e valore è corrente min, permeabile min è 2 * corrente min - superiore.
Il C++ codice di esempio è stata di:
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;
}
Questa soluzione è preso in prestito da my blog, e il mio libro "Coding Interviews: Questions, Analysis & Solutions".
fonte
2012-12-29 02:40:06
possibile duplicato di [Stack con find-min/find-max più efficiente di O (n)?] (Http://stackoverflow.com/questions/7134129/stack-with-find-min-find-max- più-efficiente-di-on) – templatetypedef