实现一个在O(1)内提供min操作的栈
来源:互联网 发布:精修图片软件 编辑:程序博客网 时间:2024/05/19 15:21
题目:
正如本文题目所示,要求实现一个除了push,pop之外,还提供一个在O(1)时间内给出堆栈内最小的数值的操作。
解析1:
对于这个问题,我们可以从堆栈节点保存的信息入手。通常堆栈的节点只保存一个数据对象,为了能够在O(1)的时间内找到堆栈内最小的值,我们可以在每个堆栈节点内保存一个min值,用于指示堆栈在该节点及其以下的所有节点中,最小的值。这样,当需要获取堆栈中目前的最小值的时候,我们只需要获取栈顶节点的min数据即可。
根据这种思想,我们不难写出代码:
#include <iostream>#include <string>using namespace std;class OutofDataException{public:OutofDataException(const string& msg);string message() const;private:string _msg;};//class OutofDataExceptionOutofDataException::OutofDataException(const string& msg):_msg(msg) {}string OutofDataException::message() const{return _msg;}//class StackWithMin{public:StackWithMin();StackWithMin(const StackWithMin& rhs);~StackWithMin();StackWithMin& operator=(const StackWithMin& rhs);void push(int data);int pop();int min() const;int size() const;bool isEmpty() const;private:void destroy();//用于销毁栈,回收内存空间struct Node//堆栈节点类型{int data;int min;Node* next;Node* clone() const;};//NodeNode* _top;int _size;};//class StackWithMintypedef StackWithMin STW;STW::Node* STW::Node::clone() const{Node* p = new Node;if(p == NULL) throw "Memory allocation failure!\n";p->data = data;p->min = min;p->next = NULL;const Node* q = this;while(q->next != NULL){p->next = new Node;p = p->next;q = q->next;p->data = q->data;p->min = q->min;p->next = NULL;}return p;}//STW::Node::copySTW::StackWithMin():_top(NULL), _size(0) {}STW::StackWithMin(const StackWithMin& rhs):_top(NULL), _size(rhs._size){if(rhs._size == 0) return;_top = rhs._top->clone();}//STW::StackWithMinSTW::~StackWithMin(){destroy();}//STW::~StackWithMinStackWithMin& STW::operator=(const StackWithMin& rhs){if(this == &rhs) return *this;Node* p = NULL;if(rhs._top != NULL) p = rhs._top->clone();destroy();_size = rhs._size;_top = p;return *this;}//STW::operator=void STW::push(int data){Node* p = new Node;if(p == NULL) throw "Memory allocation failure!\n";p->data = data;if(_top == NULL){p->min = data;p->next = NULL;}else{p->next = _top;p->min = (data<_top->min)?data:_top->min;}_top = p;_size++;}//STW::pushint STW::pop(){if(_size == 0) throw OutofDataException("堆栈为空\n");Node* p = _top;_top = _top->next;_size--;int t = p->data;delete p;return t;}//STW::popint STW::min() const{if(_size == 0) throw OutofDataException("堆栈为空\n");return _top->min;}//STW::minvoid STW::destroy(){if(_size == 0) return;_size = 0;while(_top!= NULL){Node* p = _top;_top = _top->next;delete p;}}//STW::destroybool STW::isEmpty() const{return (_size == 0);}//STW::isEmptyint main(){StackWithMin s;int x = 0;while(cin >> x && x >= 0){s.push(x);}while(!s.isEmpty()){cout << s.min() << " " << endl;s.pop();}getchar();}
解析2:
用上面的方法能够正确的提供题目所要求的方法,但是这种方法所需的空间复杂度为O(n),n为堆栈元素个数。我们其实可以做到更好,使空间复杂度在最好的情况下降为O(1),最坏的情况下为O(n).这种方法中,我们并不直接修改堆栈节点类型,而是用另外一个堆栈来保存最小值的信息。其中,保存最小值的辅助栈的节点信息中保存当前栈的最小值,以及栈中包含最小值的节点的个数。
每次入栈时,有三种情况:
1.当入栈元素值小于当前堆栈的最小元素时,才将该值以及计数值(为1)同时放入辅助栈;
2.当入栈值大于栈的最小值时,存放最小值的栈不需要做任何改变;
3.当入栈值等于当前栈的最小值时,将最小值栈栈顶节点的最小值计数加一。
每次出栈时同样包含两种情况:
1.当出栈元素值大于当前栈的最小值,只需将其从栈中弹出即可,无需对辅助栈进行任何改变;
2.当出栈元素值等于当前栈的最小值,则将辅助栈栈顶节点中的计数信息减一,当计数为零时,弹出栈顶元素;
每次要获取栈中最小元素值,只需要获取辅助栈栈顶元素的值即可。
根据这种思路,则不难给出代码:
#include <stack>#include <iostream>using namespace std;class StackWithMin{public:StackWithMin();~StackWithMin();void push();int pop();int min();bool isEmpty() const;int size() cosnt;private:stack<int> mainStack;stack<pair<int, int> > minStack;};//class StackWithMintypedef StackWithMin STW;STW::StackWithMin():_size(0) {}STW::~StackWithMin() {}void STW::push(int data){mainStack.push(data);if(minStack.empty()){minStack.push(make_pair(data, 1));}else if(data == minStack.top().first){minStack.top().second++;}}//STW::pushint STW::pop(){if(mainStack.empty()) throw "Stack is empty\n";int top = mainStack.top();mainStack.pop();if(top == minStack.top().first){minStack.top().second--;if(minStack.top().second == 0) minStack.pop();}return top;}//STW::popint STW::size() const{return mainStack.size();}//STW::sizeint STW::isEmpty() const{return mainStack.empty();}//STW::isEmpty
- 实现一个在O(1)内提供min操作的栈
- 设计栈,在O(1)的时间复杂内实现push,pop,min
- 实现一个栈,要求push,pop,Min的操作时间复杂度为O(1)
- 实现一个栈, 其 Push,Pop,Min 操作的 时间复杂度 均为 O( 1 )
- 定义栈的数据结构在Theta(1)时间复杂度内实现min,pop,push操作
- 实现一个栈Stack,要求实现Push、Pop、Min(返回最小值的操作)的时间复杂度为O(1)
- 带MIN函数的栈实现(push pop min 操作都只花O(1))
- 实现一个栈(元素遵守先入后出顺序),能够通过 min 方法在 O(1)时间内获取栈中的最小元素。同时,栈的基本操作:入栈(Push)、出栈(Pop),也是在O(1)时间内完成的
- 实现一个栈Stack,Push、Pop、Min(返回最小值的操作)的时间复杂度为O(1)
- 实现一个栈,使push,pop,min操作只需要o(1)时间
- 【栈队列】实现一个栈Stack,要求实现Push(出栈)、Pop(入栈)、Min(返回最小值的操作)的时间复杂度为O(1)
- 栈--实现一个栈Stack,要求实现Push(出栈)、Pop(入栈)、Min(返回最小值的操作)的时间复杂度为O(1)
- 【数据结构】实现一个栈,要求实现Push(出栈)、Pop(入栈)、Min(返回最小值的操作)的时间复杂度为O(1)
- 实现一个栈,要求实现Push(入栈)、Pop(出栈)、Min(返回最小值的操作)的时间复杂度为O(1)
- ~实现一个栈,要求实现Push(出栈)、Pop(入栈)、Min(返回最小值的操作)的时间复杂度为O(1)~
- 剑指offer 21---实现一个栈, 要求实现Push( 出栈) 、 Pop( 入栈) 、 Min( 返回最小值的操作) 的时间复杂度为O(1)
- 1. 实现一个栈,要求实现 Push (出栈)、 Pop (入栈)、 Min (返回最小值的操作) 的时间复杂度为 O(1)
- 实现一个栈Stack,要求实现Push(出栈)、Pop(入栈)、Min(返回最小值的操作)的时间复杂度为O(1)
- <%@ include file=""%>与<jsp:include page=""/>区别
- < C++ > string c_str
- 异构网络中的分布式拥塞控制(MKC)
- php使用curl来获取远程图片
- TestComplete9测试Flex第一步:创建工程
- 实现一个在O(1)内提供min操作的栈
- gcc spec file --sysroot
- 枚举类型转换成List
- Android开发:Activity初始化时屏蔽EditText的自动获取焦点的事件
- 记录一下八款开源 游戏引擎
- JavaScript 的性能优化:加载和执行
- CentOS下nginx的重启方法
- 多线程
- 结构体字节对齐