Question: To define the stack data structure, add a min function to obtain the minimum element of the stack. The time complexity of the min, push, and pop functions is O (1 ).
Analysis: common stack push () and POP () are all O (1). Now we need to add the min method. At first glance, I thought of adding a min variable to the stack structure to save the minimum element of the current stack. In this way, when the push () operation is performed, compare the value of the element and the min variable to determine whether to replace the min variable, that is, the push () operation O (1), but pop () it is the most troublesome, because if Pop () is the smallest element, then updating the min variable requires re-traversing the entire stack, and the time complexity is O (n ). If you continue to follow the above ideas, adding a small variable will not solve the problem of updating POP. Therefore, we need to define the minimum value of a secondary stack to store the current stack, that is, a normal data stack and a secondary stack to store the minimum element. When pushing, if the secondary stack is empty, the current element is directly pushed to the secondary stack. Otherwise, compare the current element value with the top element value of the secondary stack (that is, the previous minimum value), and take the minimum value and press it into the stack. Pop is the same as data stack. Finally, an optimization point is provided. The secondary stack can only store the index of the data stack instead of the data itself. This can reduce the memory usage. The following implementation uses the STL stack and there is no way to use the iterator to access the middle elements of the stack. Therefore, the auxiliary stack saves the data itself rather than the index.
C ++ implementation:
# Include <iostream> <br/> # include <stack> <br/> using namespace STD; </P> <p> template <typename T> <br/> class minstack {<br/> Public: <br/> void push (const T &); <br/> void POP (); <br/> T & Top (); <br/> T & min (); <br/> bool empty () {return S. empty () ;}< br/> int size () {return S. size () ;}< br/> PRIVATE: <br/> stack <t> S; <br/> stack <t> minval; <br/> }; </P> <p> template <typename T> <br/> void minstack <t>: Push (Const T & X) {<br/> S. push (x); <br/> If (minval. size () = 0) {<br/> minval. push (x); <br/>} else if (minval. top ()> = x) {<br/> minval. push (x); <br/>} else if (minval. top () <X) {<br/> minval. push (minval. top (); <br/>}</P> <p> template <typename T> <br/> void minstack <t> :: pop () {<br/> If (S. size ()! = 0) {<br/> S. pop (); <br/> minval. pop (); <br/>}else {<br/> cout <"error: Stack empty !! "<Endl; <br/>}</P> <p> template <typename T> <br/> T & minstack <t> :: top () {<br/> return S. top (); <br/>}</P> <p> template <typename T> <br/> T & minstack <t>: min () {<br/> return minval. top (); <br/>}</P> <p> template <typename T> <br/> void printstack (minstack <t> m) {<br/> If (! M. empty () {<br/> cout <"Min:" <m. min () <"/t (" <m. top (); <br/> M. pop (); <br/> while (! M. empty () {<br/> cout <"," <m. top (); <br/> M. pop (); <br/>}< br/> cout <")" <Endl; <br/>} else {<br/> cout <"Stack empty" <Endl; <br/>}</P> <p> int main () <br/>{< br/> minstack <int> MS; </P> <p> MS. push (4); cout <"Push 4! /T "; printstack (MS); <br/> MS. Push (3); cout <" Push 3! /T "; printstack (MS); <br/> MS. Push (2); cout <" Push 2! /T "; printstack (MS); <br/> MS. Push (1); cout <" Push 1! /T "; printstack (MS); <br/> MS. Push (5); cout <" Push 5! /T "; printstack (MS); <br/> while (! Ms. Empty () {<br/> MS. Pop (); <br/> cout <"pop! /T "; <br/> printstack (MS); <br/>}</P> <p> return 0; <br/>}< br/>