【剑指offer】面试题21:包含min函数的栈

题目:定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的min函数。在该栈中,调用min、push及pop的时间复杂度都是O(1)。

我们或许会想到在栈里添加一个成员变量存放最小的元素。

具体思路为:每次压入一个新元素进栈的时候,如果该元素比当前最小的元素还要小,则更新最小元素。

但是上述办法存在一个问题:如果我们做弹出操作,恰好弹出的是栈当前的最小元素?那么如何得到下一个最小的元素呢?

为此,在push一个元素的时候,我们需要辅助栈保存之前的最小元素。

具体做法为:每次push进一个元素val的时候,我们都将val与当前辅助栈的栈顶元素(最小元素)比较,然后将两者的较小者压入辅助栈,那么就能保证辅助栈的栈顶一直都是最小元素。当最小元素从数据站内被弹出之后,同时弹出辅助栈的栈顶元素,此时辅助栈的新栈顶元素就是下一个最小值。

待压入序列为:3、4、2、1、0;具体操作、数据栈、辅助栈以及最小值如下表所示

 

具体代码如下:

StackWithMin.hpp

 1 // StackWithMin.hpp
 2 #ifndef STACKWITHMIN
 3 #define STACKWITHMIN 
 4 
 5 #include <stack>
 6 #include <assert.h>
 7 
 8 template <typename T> 
 9 class StackWithMin
10 {
11 public:
12     StackWithMin() { }
13     ~StackWithMin() { }
14 
15     const T& top()const;
16 
17     bool empty()const;
18     size_t size()const;
19 
20     void push(const T &elem);
21     void pop();
22 
23     const T& min()const; 
24 
25 private:
26     std::stack<T> m_data; // 数据栈
27     std::stack<T> m_tmp; // 辅助栈
28 };
29 
30 template <typename T> 
31 const T& StackWithMin<T>::top()const
32 {
33     return m_data.top();
34 }
35 
36 template <typename T> 
37 bool StackWithMin<T>::empty()const
38 {
39     return m_data.empty();
40 }
41 
42 template <typename T> 
43 size_t StackWithMin<T>::size()const
44 {
45     return m_data.size();
46 }
47 
48 template <typename T> 
49 void StackWithMin<T>::push(const T &elem)
50 {
51     // 放入数据栈
52     m_data.push(elem);
53 
54     // 放入辅助栈
55     // 如果比现有最小值小,则push该elem;如果比现有最小值大,则push辅助栈的栈顶
56     if(m_tmp.empty() || m_tmp.top() > elem)
57         m_tmp.push(elem);
58     else
59         m_tmp.push(m_tmp.top());
60 }
61 
62 template <typename T> 
63 void StackWithMin<T>::pop()
64 {
65     assert(!m_data.empty() || !m_tmp.empty());
66 
67     m_data.pop();
68     m_tmp.pop();
69 }
70 
71 template <typename T> 
72 const T& StackWithMin<T>::min()const
73 {
74     return m_tmp.top();
75 }
76 
77 #endif/* STACKWITHMIN */
View Code

测试代码如下:

main.cpp

 1 // main.cpp
 2 #include "StackWithMin.hpp"
 3 #include <iostream>
 4 #include <time.h>
 5 #include <stdlib.h>
 6 using namespace std;
 7 
 8 int main(int argc, char const *argv[])
 9 {
10     srand(time(NULL));
11     StackWithMin<int> st;
12 
13     int n = 10;
14 
15     while(n--)
16     {
17         int num = rand() % 100;
18         cout << "Push num " << num;
19         st.push(num);
20         cout << ", Test " << (10-n) << ": Min num is " << st.min() << endl;
21     }
22     cout << "The size is: " << st.size() << endl;
23 
24     while(++n < 5)
25     {
26         st.pop();
27     }
28     cout << "The min num is: " << st.min() << endl;
29     cout << "The size is: " << st.size() << endl;
30     
31     return 0;
32 }
View Code

本文完。

原文地址:https://www.cnblogs.com/xfxu/p/4616496.html