面试100题:2.设计包含min函数的栈
来源:互联网 发布:监控远程控制软件 编辑:程序博客网 时间:2024/06/05 20:25
题目:
定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素。要求函数min、push以及pop的时间复杂度都是O(1)。结合链表一起做。提示:结合链表一起做。
分析:
要想求得复杂度是O(1)的算法,基本思路是设计一个辅助栈,该栈随时更新保存的当前所有数据的最小值。即一发现有更小的值,就把数据压入该辅助站中。
解一:
利用C++的Template可以增强代码的复用性。同时,结合vector类型内置的push_back(),pop_back()函数可以简化操作。
- /*Title: 2.设计包含min函数的栈:解一
- Author: gocode
- Date: 2012-09-29*/
- #include <iostream>
- #include <assert.h>
- #include <vector>
- using namespace std;
- template <typename T>
- class StackSuppliedMin
- {
- public:
- vector<T> datas; // 保存值的数据栈
- vector<T> minStack; // 辅助栈,保存最小值位置,记住这里只是记录了最小值在datas的位置
- // 进栈操作
- void Push(T data)
- {
- datas.push_back(data);
- if (minStack.empty() || data < datas[minStack.back()])
- minStack.push_back(datas.size()-1);
- }
- // 出栈操作
- void Pop()
- {
- //assert(!datas.empty());
- if (!datas.empty() && datas.back() == datas[minStack.back()])
- minStack.pop_back();
- datas.pop_back();
- }
- // 返回栈顶数据值
- T Peek()
- {
- //assert(!datas.empty());
- if (!datas.empty())
- return datas.back();
- else
- {
- cout<<"Data stack is empty.";
- return NULL;
- }
- }
- // 获得最小值
- T GetMinimal()
- {
- //assert(!datas.empty() && !minStack.empty());
- if (!datas.empty() && !minStack.empty())
- return datas[minStack.back()];
- else
- {
- cout<<"Minimal stack is empty.";
- return NULL;
- }
- }
- // 列出栈里的数据
- void displayStack(vector<T> theStack)
- {
- if (!theStack.empty())
- {
- for (vector<T>::iterator it = theStack.begin(); it != theStack.end(); ++it)
- cout<<*it<<" ";
- cout<<endl;
- }
- else
- cout<<"No data in the stack."<<endl;
- }
- };
- void main()
- {
- StackSuppliedMin<int> myStackClass;
- // 推进栈,并显示变化情况
- myStackClass.Push(2);
- cout<<"After push "<<myStackClass.Peek()<<" the 2 stacks contain: "<<endl;
- myStackClass.displayStack(myStackClass.datas);
- myStackClass.displayStack(myStackClass.minStack);
- cout<<endl;
- myStackClass.Push(6);
- cout<<"After push "<<myStackClass.Peek()<<" the 2 stacks contain: "<<endl;
- myStackClass.displayStack(myStackClass.datas);
- myStackClass.displayStack(myStackClass.minStack);
- cout<<endl;
- myStackClass.Push(4);
- cout<<"After push "<<myStackClass.Peek()<<" the 2 stacks contain: "<<endl;
- myStackClass.displayStack(myStackClass.datas);
- myStackClass.displayStack(myStackClass.minStack);
- cout<<endl;
- myStackClass.Push(1);
- cout<<"After push "<<myStackClass.Peek()<<" the 2 stacks contain: "<<endl;
- myStackClass.displayStack(myStackClass.datas);
- myStackClass.displayStack(myStackClass.minStack);
- cout<<endl;
- myStackClass.Push(5);
- cout<<"After push "<<myStackClass.Peek()<<" the 2 stacks contain: "<<endl;
- myStackClass.displayStack(myStackClass.datas);
- myStackClass.displayStack(myStackClass.minStack);
- cout<<endl;
- cout<<"Current stacks status: "<<endl;
- myStackClass.displayStack(myStackClass.datas);
- myStackClass.displayStack(myStackClass.minStack);
- cout<<endl;
- // 弹出栈,并显示当前变化情况
- cout<<"The top data in statck is: "<<myStackClass.Peek()<<endl;
- myStackClass.Pop();
- cout<<"After pop the minimal data: "<<myStackClass.GetMinimal()<<endl;
- cout<<"After pop the 2 stacks contain: "<<endl;
- myStackClass.displayStack(myStackClass.datas);
- myStackClass.displayStack(myStackClass.minStack);
- cout<<endl;
- cout<<"The top data in statck is: "<<myStackClass.Peek()<<endl;
- myStackClass.Pop();
- cout<<"After pop the minimal data: "<<myStackClass.GetMinimal()<<endl;
- cout<<"After pop the 2 stacks contain: "<<endl;
- myStackClass.displayStack(myStackClass.datas);
- myStackClass.displayStack(myStackClass.minStack);
- cout<<endl;
- cout<<"The top data in statck is: "<<myStackClass.Peek()<<endl;
- myStackClass.Pop();
- cout<<"After pop the minimal data: "<<myStackClass.GetMinimal()<<endl;
- cout<<"After pop the 2 stacks contain: "<<endl;
- myStackClass.displayStack(myStackClass.datas);
- myStackClass.displayStack(myStackClass.minStack);
- cout<<endl;
- cout<<"The top data in statck is: "<<myStackClass.Peek()<<endl;
- myStackClass.Pop();
- cout<<"After pop the minimal data: "<<myStackClass.GetMinimal()<<endl;
- cout<<"After pop the 2 stacks contain: "<<endl;
- myStackClass.displayStack(myStackClass.datas);
- myStackClass.displayStack(myStackClass.minStack);
- cout<<endl;
- cout<<"The top data in statck is: "<<myStackClass.Peek()<<endl;
- myStackClass.Pop();
- cout<<"After pop the minimal data: "<<myStackClass.GetMinimal()<<endl;
- cout<<"After pop the 2 stacks contain: "<<endl;
- myStackClass.displayStack(myStackClass.datas);
- myStackClass.displayStack(myStackClass.minStack);
- cout<<endl;
- system("pause");
- }
结果:
解二:
使用传统链表构造栈,链表节点有两个值,一个是当前节点的值,另一个是栈中最小值。这样同样能够解决问题。
- /*Title: 2.设计包含min函数的栈:解二
- Author: gocode
- Date: 2012-09-29*/
- #include <iostream>
- using namespace std;
- struct MinStackElement
- {
- int data;
- int min;
- };
- struct MinStack
- {
- MinStackElement *item;
- int size;
- int top;
- };
- MinStack MinStackInit(int maxSize)
- {
- MinStack stack;
- stack.size = maxSize;
- stack.item = (MinStackElement *) malloc (sizeof(MinStackElement)*maxSize);
- stack.top = 0;
- return stack;
- }
- void MinStackFree(MinStack stack)
- {
- free(stack.item);
- stack.size = 0; // 表示栈里数据的容量
- stack.top = 0; // 表示栈顶
- }
- // 把数值压入栈顶
- void MinStackPush(MinStack &stack, int d)
- {
- if (stack.top == stack.size)
- {
- cout<<"out of stack space."<<endl;
- return;
- }
- // 指向栈顶,并赋值d
- MinStackElement *p = &stack.item[stack.top];
- p->data = d;
- // 先赋值原最小值,然后和data作比较判断出当前最小值
- p->min = (stack.top==0 ? d : stack.item[stack.top-1].min);
- if (p->min > d)
- p->min = d;
- stack.top++;
- }
- // 弹出栈中栈顶数据
- void MinStackPop(MinStack &stack)
- {
- if (stack.top == 0)
- {
- cout<<"stack is empty."<<endl;
- return ;
- }
- --stack.top;
- }
- // 求得栈中当前最小值
- int MinStackMin(MinStack &stack)
- {
- if (stack.top == 0)
- {
- cout<<"stack is empty."<<endl;
- return NULL;
- }
- return stack.item[stack.top-1].min;
- }
- int MinStackPeek(MinStack stack)
- {
- if (stack.top == 0)
- {
- cout<<"stack is empty."<<endl;
- return NULL;
- }
- return stack.item[stack.top-1].data;
- }
- // 显示栈中数据
- void MinStackDisplay(MinStack stack)
- {
- if (stack.size == 0)
- {
- cout<<"stack is empty."<<endl;
- return;
- }
- else
- {
- for (int i = 0; i < stack.top; i++)
- {
- cout<<stack.item[i].data<<" ";
- }
- cout<<endl;
- }
- }
- void main()
- {
- MinStack thestack = MinStackInit(5);
- MinStackPush(thestack, 2);
- MinStackPush(thestack, 6);
- MinStackPush(thestack, 4);
- MinStackPush(thestack, 1);
- MinStackPush(thestack, 5);
- MinStackDisplay(thestack);
- cout<<"Pop the value "<<MinStackPeek(thestack)<<endl;
- MinStackPop(thestack);
- cout<<"Minimal value is: "<<MinStackMin(thestack)<<endl;
- MinStackDisplay(thestack);
- cout<<"Pop the value "<<MinStackPeek(thestack)<<endl;
- MinStackPop(thestack);
- cout<<"Minimal value is: "<<MinStackMin(thestack)<<endl;
- MinStackDisplay(thestack);
- cout<<"Pop the value "<<MinStackPeek(thestack)<<endl;
- MinStackPop(thestack);
- cout<<"Minimal value is: "<<MinStackMin(thestack)<<endl;
- MinStackDisplay(thestack);
- cout<<"Pop the value "<<MinStackPeek(thestack)<<endl;
- MinStackPop(thestack);
- cout<<"Minimal value is: "<<MinStackMin(thestack)<<endl;
- MinStackDisplay(thestack);
- cout<<"Pop the value "<<MinStackPeek(thestack)<<endl;
- MinStackPop(thestack);
- cout<<"Minimal value is: "<<MinStackMin(thestack)<<endl;
- MinStackDisplay(thestack);
- system("pause");
- }
结果:
0 0
- 面试100题:2.设计包含min函数的栈
- 面试100题:2.设计包含min函数的栈
- [微软面试100题] 设计包含min函数的栈
- 【微软面试100题】2.设计包含min函数的栈
- 程序员面试100题---2.设计包含 min 函数的栈
- 算法面试100题——2.设计包含min函数的栈
- (微软100题)2.设计包含min 函数的栈。
- 微软等面试100题第二题:设计包含min函数的栈
- 微软面试100题之二 设计包含min函数的栈。
- (微软面试100题)设计包含min 函数的栈
- 微软等面试100题筛选答案-2-设计包含min函数的栈
- 微软面试100题系列-设计包含 min 函数的栈
- 微软面试100题系列---设计包含min函数的栈
- 2.设计包含min函数的栈
- 2.设计包含min函数的栈
- 2.设计包含min 函数的栈。
- 2.设计包含min函数的栈
- 2.设计包含min 函数的栈
- cocos2dx项目中新增场景类
- spring详解(一)
- myeclipse 一些提示信息快捷键设置
- HDU 1978 DP
- 动态规划与贪心算法
- 面试100题:2.设计包含min函数的栈
- 函数指针和回调函数
- 2013年五大主流浏览器 HTML5 和 CSS3 兼容性大比拼
- perl中重要的几个命令行参数
- 如何跟踪调试Android的源码
- win32 查找注册表找网卡
- 路径的写法
- Android permission 访问权限大全
- 在eclise与Maven进行junit单元测试无法自动编译