17_7_19:实现一个栈要求实现入栈、出栈、获得最小值的时间复杂度为O(1)
2017-07-19 23:58
246 查看
问题描述:
实现一个栈Stack,要求实现Push(出栈)、Pop(入栈)、Min(返回最小值的操作)的时间复杂度为O(1) 。
难点分析:
首先,我们知道,在栈的实现中,入栈、出栈操作的时间复杂度都是O(1)。
难就难在返回最小值的操作的时间复杂度。如果有一个值来存储的话,到时可以,但是,当有入栈,出栈操作时,这个最小值是不断变换着的。
所以,难点可以看成是:最小值如何存储,才能满足栈中元素的动态变换呢?
思路:
虽然栈中元素可能动态变换,但是也要满足“后进先出”的原则。
当入栈的元素,小于存储的最小值时,我们要更新最小值;当最小值出栈时,我们也要更新最小值。
也就是说,我们也要动态的存储栈中出现过的最小值,知道这个元素出栈。
这样,我们可以利用两个栈s1,s2,一个专门存储数据集合,一个专门存储数据中的最小值集合。
当一个数据data入栈时,存储到第一个栈s1中,并且和第二个栈s2中的栈顶元素s2.top()比较大小。如果data<=s2.top(),那么也存储到s2中,这样当返回最小值时,直接就可以从s2中取,时间复杂度O(1)。
当一个数据data出栈时,和第二个栈中元素s2.top()比较,如果data=s2.top。则说明,此时出栈的元素是最小值。那么就要s1,s2都要出栈。来更新数据栈,以及最小值栈。此时,返回最小值时,直接就可一个从s2中取,时间复杂度O(1)。
可以发现,利用栈的“后进先出”规则,可以用来,动态更新最小值结婚。并且,位于栈顶的永远是最小的。从上往下,最小值数据依次变大。
值得注意的是:数据入栈时和最小值栈顶元素比较时,一定是“<=”,这样可以避免多个值相同数据,出栈时造成的错误。
实现代码:
测试用例:
实现一个栈Stack,要求实现Push(出栈)、Pop(入栈)、Min(返回最小值的操作)的时间复杂度为O(1) 。
难点分析:
首先,我们知道,在栈的实现中,入栈、出栈操作的时间复杂度都是O(1)。
难就难在返回最小值的操作的时间复杂度。如果有一个值来存储的话,到时可以,但是,当有入栈,出栈操作时,这个最小值是不断变换着的。
所以,难点可以看成是:最小值如何存储,才能满足栈中元素的动态变换呢?
思路:
虽然栈中元素可能动态变换,但是也要满足“后进先出”的原则。
当入栈的元素,小于存储的最小值时,我们要更新最小值;当最小值出栈时,我们也要更新最小值。
也就是说,我们也要动态的存储栈中出现过的最小值,知道这个元素出栈。
这样,我们可以利用两个栈s1,s2,一个专门存储数据集合,一个专门存储数据中的最小值集合。
当一个数据data入栈时,存储到第一个栈s1中,并且和第二个栈s2中的栈顶元素s2.top()比较大小。如果data<=s2.top(),那么也存储到s2中,这样当返回最小值时,直接就可以从s2中取,时间复杂度O(1)。
当一个数据data出栈时,和第二个栈中元素s2.top()比较,如果data=s2.top。则说明,此时出栈的元素是最小值。那么就要s1,s2都要出栈。来更新数据栈,以及最小值栈。此时,返回最小值时,直接就可一个从s2中取,时间复杂度O(1)。
可以发现,利用栈的“后进先出”规则,可以用来,动态更新最小值结婚。并且,位于栈顶的永远是最小的。从上往下,最小值数据依次变大。
值得注意的是:数据入栈时和最小值栈顶元素比较时,一定是“<=”,这样可以避免多个值相同数据,出栈时造成的错误。
实现代码:
#include <iostream> #include <stack> #include <cassert> #include <time.h> //用来生成随机数 template <typename T> class Stack { public: void Push(const T& data) { _s_1.push(data); //当_s_2为空时,_s_1原来肯定也为空,实现的栈中数据,只有一个。 if (_s_2.empty()) { _s_2.push(data); return; } //如果,入栈数据小于等于实现栈中的最小值,也入栈 T &min = _s_2.top(); if (data <= min) _s_2.push(data); } void Pop() { if (_s_1.empty()) //_s_1为空,_s_2也为空,当做一种情况。 assert(0); //如果出栈元素,等于最小值,则,两个一起出栈,否则,只有数据出栈,最小值不变 if (_s_1.top() == _s_2.top()) _s_2.pop(); _s_1.pop(); } T& Get_Min() { if (_s_2.empty()) assert(0); return _s_2.top(); } private: std::stack<T> _s_1; std::stack<T> _s_2; };
测试用例:
int main() { Stack<int> s; srand((unsigned)time(NULL)); //以时间作为随机数种子 for (int i = 0; i < 100; ++i) s.Push(rand()); //测试用例,输出应该是从小到大递增 for (int i = 0; i < 100; ++i) { std::cout <<i<<":"<< s.Get_Min() << std::endl; s.Pop(); } system("pause"); return 0; }
相关文章推荐
- 实现一个栈,要求push(入栈),pop(出栈),min(返回栈中的最小值)的时间复杂度为O(1);
- 实现一个栈Stack,要求实现Push(入栈)、Pop(出栈)、Min(返回最小值的操作)的时间复杂度为O(1)
- 实现一个栈,要求实现Push(入栈)、Pop(出栈)、Min(返回最小值的操作)的时间复杂度为O(1)
- O(1)时间复杂度实现入栈、出栈、获得栈中最小元素、获得栈中最大元素
- 实现一个栈Stack,要求实现Push(出栈)、Pop(入栈)、Min(返回最小值的操作)的时间复杂度为O(1)
- 模拟实现一个Stack 要求实现Push(出栈)、Pop(入栈)、Min(返回最小值的操作)的时间复杂度为O(1)
- 实现一个栈,要求实现Push(入栈)、Pop(出栈)、Min(返回最小值的操作)的时间复杂度为O(1)
- 实现一个栈,要求实现Push(出栈)、Pop(入栈)、Min(返回最小值的操作)的时间复杂度为O(1)
- 定义一个栈的数据结构,要求实现一个min函数,每次能够得到栈的最小值,并且要求Min的时间复杂度为O(1)
- 【每日一题】实现一个栈Stack,要求实现Push(出栈)、Pop(入栈)、 Min(返回最小值的操作)的时间复杂度为O(1)
- 【栈队列】实现一个栈Stack,要求实现Push(出栈)、Pop(入栈)、Min(返回最小值的操作)的时间复杂度为O(1)
- 实现一个栈Stack,要求实现Push(出栈)、Pop(入栈)、Min(返回最小值的操作)的时间复杂度为O(1)
- 定义一个栈的数据结构,要求实现一个min函数,每次能够得到栈的最小值,并且要求Min的时间复杂度为O(1)
- 定义一个栈的数据结构,要求实现一个min函数,每次能够得到栈的最小值,并且要求Min的时间复杂度为O(1)
- 实现一个栈Stack,要求实现Push(出栈)、Pop(入栈)、Min(返回最小值的操作)的时间复杂度为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)
- 【每日一题】实现一个栈Stack,要求实现Push(出栈)、Pop(入栈)、Min(返回最小值的操作)的时间复杂度为O(1)