面试100题:2.设计包含min函数的栈

来源:互联网 发布:监控远程控制软件 编辑:程序博客网 时间:2024/06/05 20:25

题目

定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素。要求函数min、push以及pop的时间复杂度都是O(1)。结合链表一起做。提示:结合链表一起做。

分析

要想求得复杂度是O(1)的算法,基本思路是设计一个辅助栈,该栈随时更新保存的当前所有数据的最小值。即一发现有更小的值,就把数据压入该辅助站中。

解一

利用C++Template可以增强代码的复用性。同时,结合vector类型内置的push_back(),pop_back()函数可以简化操作。

  1. /*Title: 2.设计包含min函数的栈:解一 
  2. Author:  gocode 
  3. Date:    2012-09-29*/  
  4.   
  5. #include <iostream>  
  6. #include <assert.h>  
  7. #include <vector>  
  8. using namespace std;  
  9.   
  10. template <typename T>  
  11. class StackSuppliedMin  
  12. {  
  13. public:  
  14.     vector<T> datas; // 保存值的数据栈  
  15.     vector<T> minStack; // 辅助栈,保存最小值位置,记住这里只是记录了最小值在datas的位置  
  16.   
  17.     // 进栈操作  
  18.     void Push(T data)  
  19.     {  
  20.         datas.push_back(data);  
  21.         if (minStack.empty() || data < datas[minStack.back()])  
  22.             minStack.push_back(datas.size()-1);  
  23.     }  
  24.   
  25.     // 出栈操作  
  26.     void Pop()  
  27.     {  
  28.         //assert(!datas.empty());  
  29.         if (!datas.empty() && datas.back() == datas[minStack.back()])  
  30.             minStack.pop_back();  
  31.         datas.pop_back();  
  32.     }  
  33.   
  34.     // 返回栈顶数据值  
  35.     T Peek()  
  36.     {  
  37.         //assert(!datas.empty());  
  38.         if (!datas.empty())  
  39.             return datas.back();  
  40.         else  
  41.         {  
  42.             cout<<"Data stack is empty.";  
  43.             return NULL;  
  44.         }  
  45.     }  
  46.     // 获得最小值  
  47.     T GetMinimal()  
  48.     {  
  49.         //assert(!datas.empty() && !minStack.empty());  
  50.         if (!datas.empty() && !minStack.empty())  
  51.             return datas[minStack.back()];  
  52.         else  
  53.         {  
  54.             cout<<"Minimal stack is empty.";  
  55.             return NULL;  
  56.         }  
  57.     }  
  58.   
  59.     // 列出栈里的数据  
  60.     void displayStack(vector<T> theStack)  
  61.     {  
  62.         if (!theStack.empty())  
  63.         {  
  64.             for (vector<T>::iterator it = theStack.begin(); it != theStack.end(); ++it)  
  65.                 cout<<*it<<" ";  
  66.    
  67.             cout<<endl;  
  68.         }  
  69.         else  
  70.             cout<<"No data in the stack."<<endl;  
  71.     }  
  72. };  
  73.   
  74. void main()  
  75. {  
  76.     StackSuppliedMin<int> myStackClass;  
  77.   
  78.     // 推进栈,并显示变化情况  
  79.     myStackClass.Push(2);  
  80.     cout<<"After push "<<myStackClass.Peek()<<" the 2 stacks contain: "<<endl;  
  81.     myStackClass.displayStack(myStackClass.datas);  
  82.     myStackClass.displayStack(myStackClass.minStack);  
  83.     cout<<endl;  
  84.   
  85.     myStackClass.Push(6);  
  86.     cout<<"After push "<<myStackClass.Peek()<<" the 2 stacks contain: "<<endl;  
  87.     myStackClass.displayStack(myStackClass.datas);  
  88.     myStackClass.displayStack(myStackClass.minStack);  
  89.     cout<<endl;  
  90.   
  91.     myStackClass.Push(4);  
  92.     cout<<"After push "<<myStackClass.Peek()<<" the 2 stacks contain: "<<endl;  
  93.     myStackClass.displayStack(myStackClass.datas);  
  94.     myStackClass.displayStack(myStackClass.minStack);  
  95.     cout<<endl;  
  96.   
  97.     myStackClass.Push(1);  
  98.     cout<<"After push "<<myStackClass.Peek()<<" the 2 stacks contain: "<<endl;  
  99.     myStackClass.displayStack(myStackClass.datas);  
  100.     myStackClass.displayStack(myStackClass.minStack);  
  101.     cout<<endl;  
  102.   
  103.     myStackClass.Push(5);  
  104.     cout<<"After push "<<myStackClass.Peek()<<" the 2 stacks contain: "<<endl;  
  105.     myStackClass.displayStack(myStackClass.datas);  
  106.     myStackClass.displayStack(myStackClass.minStack);  
  107.     cout<<endl;  
  108.   
  109.     cout<<"Current stacks status: "<<endl;  
  110.     myStackClass.displayStack(myStackClass.datas);  
  111.     myStackClass.displayStack(myStackClass.minStack);  
  112.     cout<<endl;  
  113.   
  114.     // 弹出栈,并显示当前变化情况  
  115.     cout<<"The top data in statck is: "<<myStackClass.Peek()<<endl;  
  116.     myStackClass.Pop();  
  117.     cout<<"After pop the minimal data: "<<myStackClass.GetMinimal()<<endl;  
  118.     cout<<"After pop the 2 stacks contain: "<<endl;  
  119.     myStackClass.displayStack(myStackClass.datas);  
  120.     myStackClass.displayStack(myStackClass.minStack);  
  121.     cout<<endl;  
  122.   
  123.     cout<<"The top data in statck is: "<<myStackClass.Peek()<<endl;  
  124.     myStackClass.Pop();  
  125.     cout<<"After pop the minimal data: "<<myStackClass.GetMinimal()<<endl;  
  126.     cout<<"After pop the 2 stacks contain: "<<endl;  
  127.     myStackClass.displayStack(myStackClass.datas);  
  128.     myStackClass.displayStack(myStackClass.minStack);  
  129.     cout<<endl;  
  130.   
  131.     cout<<"The top data in statck is: "<<myStackClass.Peek()<<endl;  
  132.     myStackClass.Pop();  
  133.     cout<<"After pop the minimal data: "<<myStackClass.GetMinimal()<<endl;  
  134.     cout<<"After pop the 2 stacks contain: "<<endl;  
  135.     myStackClass.displayStack(myStackClass.datas);  
  136.     myStackClass.displayStack(myStackClass.minStack);  
  137.     cout<<endl;  
  138.   
  139.     cout<<"The top data in statck is: "<<myStackClass.Peek()<<endl;  
  140.     myStackClass.Pop();  
  141.     cout<<"After pop the minimal data: "<<myStackClass.GetMinimal()<<endl;  
  142.     cout<<"After pop the 2 stacks contain: "<<endl;  
  143.     myStackClass.displayStack(myStackClass.datas);  
  144.     myStackClass.displayStack(myStackClass.minStack);  
  145.     cout<<endl;  
  146.   
  147.     cout<<"The top data in statck is: "<<myStackClass.Peek()<<endl;  
  148.     myStackClass.Pop();  
  149.     cout<<"After pop the minimal data: "<<myStackClass.GetMinimal()<<endl;  
  150.     cout<<"After pop the 2 stacks contain: "<<endl;  
  151.     myStackClass.displayStack(myStackClass.datas);  
  152.     myStackClass.displayStack(myStackClass.minStack);  
  153.     cout<<endl;  
  154.   
  155.     system("pause");  
  156. }  

结果
 

解二

使用传统链表构造栈,链表节点有两个值,一个是当前节点的值,另一个是栈中最小值。这样同样能够解决问题。

  1. /*Title: 2.设计包含min函数的栈:解二 
  2. Author:  gocode 
  3. Date:    2012-09-29*/  
  4.   
  5. #include <iostream>  
  6. using namespace std;  
  7.   
  8. struct MinStackElement  
  9. {  
  10.     int data;  
  11.     int min;  
  12. };  
  13.   
  14. struct MinStack  
  15. {  
  16.     MinStackElement *item;  
  17.     int size;  
  18.     int top;  
  19. };  
  20.   
  21. MinStack MinStackInit(int maxSize)  
  22. {  
  23.     MinStack stack;  
  24.     stack.size = maxSize;  
  25.     stack.item = (MinStackElement *) malloc (sizeof(MinStackElement)*maxSize);  
  26.     stack.top = 0;  
  27.     return stack;  
  28. }  
  29.   
  30. void MinStackFree(MinStack stack)  
  31. {  
  32.     free(stack.item);  
  33.     stack.size = 0; // 表示栈里数据的容量  
  34.     stack.top = 0; // 表示栈顶  
  35. }  
  36.   
  37. // 把数值压入栈顶  
  38. void MinStackPush(MinStack &stack, int d)  
  39. {  
  40.     if (stack.top == stack.size)  
  41.     {  
  42.             cout<<"out of stack space."<<endl;  
  43.             return;  
  44.     }  
  45.    
  46.     // 指向栈顶,并赋值d  
  47.     MinStackElement *p = &stack.item[stack.top];  
  48.     p->data = d;  
  49.     // 先赋值原最小值,然后和data作比较判断出当前最小值  
  50.     p->min = (stack.top==0 ? d : stack.item[stack.top-1].min);  
  51.     if (p->min > d)  
  52.         p->min = d;  
  53.     stack.top++;  
  54. }  
  55.   
  56. // 弹出栈中栈顶数据  
  57. void MinStackPop(MinStack &stack)  
  58. {  
  59.     if (stack.top == 0)  
  60.     {  
  61.         cout<<"stack is empty."<<endl;  
  62.         return ;  
  63.     }  
  64.     --stack.top;  
  65. }  
  66.   
  67. // 求得栈中当前最小值  
  68. int MinStackMin(MinStack &stack)  
  69. {  
  70.     if (stack.top == 0)  
  71.     {  
  72.         cout<<"stack is empty."<<endl;  
  73.         return NULL;  
  74.     }  
  75.     return stack.item[stack.top-1].min;  
  76. }  
  77.   
  78. int MinStackPeek(MinStack stack)  
  79. {  
  80.     if (stack.top == 0)  
  81.     {  
  82.         cout<<"stack is empty."<<endl;  
  83.         return NULL;  
  84.     }  
  85.     return stack.item[stack.top-1].data;  
  86. }  
  87.   
  88. // 显示栈中数据  
  89. void MinStackDisplay(MinStack stack)  
  90. {  
  91.     if (stack.size == 0)  
  92.     {  
  93.         cout<<"stack is empty."<<endl;  
  94.         return;  
  95.     }  
  96.     else  
  97.     {  
  98.         for (int i = 0; i < stack.top; i++)  
  99.         {  
  100.             cout<<stack.item[i].data<<" ";  
  101.         }  
  102.         cout<<endl;  
  103.     }  
  104. }  
  105.   
  106. void main()  
  107. {  
  108.     MinStack thestack = MinStackInit(5);  
  109.     MinStackPush(thestack, 2);  
  110.     MinStackPush(thestack, 6);  
  111.     MinStackPush(thestack, 4);  
  112.     MinStackPush(thestack, 1);  
  113.     MinStackPush(thestack, 5);  
  114.   
  115.     MinStackDisplay(thestack);  
  116.   
  117.     cout<<"Pop the value "<<MinStackPeek(thestack)<<endl;  
  118.     MinStackPop(thestack);  
  119.     cout<<"Minimal value is: "<<MinStackMin(thestack)<<endl;  
  120.     MinStackDisplay(thestack);  
  121.   
  122.     cout<<"Pop the value "<<MinStackPeek(thestack)<<endl;  
  123.     MinStackPop(thestack);  
  124.     cout<<"Minimal value is: "<<MinStackMin(thestack)<<endl;  
  125.     MinStackDisplay(thestack);  
  126.   
  127.     cout<<"Pop the value "<<MinStackPeek(thestack)<<endl;  
  128.     MinStackPop(thestack);  
  129.     cout<<"Minimal value is: "<<MinStackMin(thestack)<<endl;  
  130.     MinStackDisplay(thestack);  
  131.   
  132.     cout<<"Pop the value "<<MinStackPeek(thestack)<<endl;  
  133.     MinStackPop(thestack);  
  134.     cout<<"Minimal value is: "<<MinStackMin(thestack)<<endl;  
  135.     MinStackDisplay(thestack);  
  136.   
  137.     cout<<"Pop the value "<<MinStackPeek(thestack)<<endl;  
  138.     MinStackPop(thestack);  
  139.     cout<<"Minimal value is: "<<MinStackMin(thestack)<<endl;  
  140.     MinStackDisplay(thestack);  
  141.     system("pause");  
  142. }  

结果

0 0