编程之美系列之栈和队列2—在O(1)的时间内得到队列的最大或者最小值
2013-04-30 15:00
288 查看
上一篇博客http://blog.csdn.net/kay_zhyu/article/details/8869542中提到,在O(1)的时间内取得栈的最大或者最小值,作法是利用一个辅助栈去动态的维护这个最小值。但是如果要在O(1)的时间内取得队列的最小值,那这就有点难办的吧。毕竟队列的操作特点是先进先出,跟栈的完全相反的,我们没办法像栈那要用一个动态的数组去维护这个最小值。怎么办呢?既然栈的最小值是很好维护的,那么有没有可以用栈来模拟队列呢?答案是肯定的啦!用栈模拟队列,那么就利用前面讲过的类似的思想就可以在O(1)的复杂度里面得到最小值了。
怎么用栈来模拟队列?这里需要用到两个栈,在stack1里面加元素,然后出栈的时候,首先看stack2里面有没有元素,如果有,直接将stack2里面的元素出栈,如果没有,OK,把stack1里面的数据依次pop掉,然后压入stack2中,然后stack2的栈顶元素出栈就可以了。那么,stack2和stack1中元素的关系就是,stack2中的元素一定比stack1中的元素先进队列,并且stack2中元素的进队列顺序是:顶早底晚,而stack1中元素的进队列顺序是:顶晚低早。OK,搞清这个关系,那就可以把这个模拟队列中的元素打印出来啦~~
时间分析:由于每个元素从进队列到出队列,它们经过的操作是:push到stack1中->从stack1中pop,然后push到stack2中->从stack2中pop。OK,那push,pop的时间复杂度都是O(1)了。对于队列的最小值,那就是两个辅助栈栈顶元素的最小值,同样是O(1)的操作。我得意的笑~~~得意的笑~~~~~(各位大爷转载请注明出处哦:
http://blog.csdn.net/kay_zhyu/article/details/8869641,小女子在此拜谢~~)OK,给上代码:
怎么用栈来模拟队列?这里需要用到两个栈,在stack1里面加元素,然后出栈的时候,首先看stack2里面有没有元素,如果有,直接将stack2里面的元素出栈,如果没有,OK,把stack1里面的数据依次pop掉,然后压入stack2中,然后stack2的栈顶元素出栈就可以了。那么,stack2和stack1中元素的关系就是,stack2中的元素一定比stack1中的元素先进队列,并且stack2中元素的进队列顺序是:顶早底晚,而stack1中元素的进队列顺序是:顶晚低早。OK,搞清这个关系,那就可以把这个模拟队列中的元素打印出来啦~~
时间分析:由于每个元素从进队列到出队列,它们经过的操作是:push到stack1中->从stack1中pop,然后push到stack2中->从stack2中pop。OK,那push,pop的时间复杂度都是O(1)了。对于队列的最小值,那就是两个辅助栈栈顶元素的最小值,同样是O(1)的操作。我得意的笑~~~得意的笑~~~~~(各位大爷转载请注明出处哦:
http://blog.csdn.net/kay_zhyu/article/details/8869641,小女子在此拜谢~~)OK,给上代码:
#include<stdio.h> const int N = 30; const int Inf = 1e5; int stack1 ;//从stack1顶进 int stack2 ;//从stack2顶出 int top1; int top2; int MinStack1 ; int MinStack2 ; inline int min(const int a, const int b) { return a < b ? a : b; } //往栈里面加元素,其实这个函数是在上一节里面定义的函数,直接拿过来就可以用了 void Add(int *stack, int *MinStack, int &top, int v) { if(top > -1) { stack[++top] = v; MinStack[top] = min(MinStack[top - 1], v); } else stack[top] = MinStack[++top] = v; } //往队列里面加元素 void Push(int v) { Add(stack1, MinStack1, top1, v); } //删除队列头的元素 void Pop() { if(top2 > -1) --top2; else { while(top1 > 0) { Add(stack2, MinStack2, top2, stack1[top1]); --top1; } top1 = -1; } } //打印队列里面的元素 void Print() { //stack2从栈顶到底 if(top2 > -1) { for(int i = top2; i >= 0; --i) printf("%d ", stack2[i]); } //stack1从栈底到顶 if(top1 > -1) { for(int i = 0; i <= top1; ++i) printf("%d ", stack1[i]); } } //获得队列的最小值 int GetMinOfQueue() { int Min = Inf; if(top1 > -1) Min = MinStack1[top1]; if(top2 > -1) Min = min(Min, MinStack2[top2]); return Min; } int main() { int IsPush,i,v; int Min; top1 = top2 = -1; printf("输入操作选项:\n0 删除栈顶元素 1 增加元素 其它 得到最小值 EOF 退出:"); while(scanf("%d", &IsPush) != EOF) { if(IsPush == 1) { printf("输入要添加的数:"); scanf("%d", &v); Push(v); } else if(!IsPush) { Pop(); } else { Min = GetMinOfQueue(); if(Min < Inf) { Print(); printf("\n最小值为:%d\n", Min); } else printf("空队列\n"); } printf("输入操作选项:\n0 删除栈顶元素 1 增加元素 其它 得到最小值 EOF 退出:"); }//end while }
相关文章推荐
- 编程之美系列之栈和队列1—在O(1)的时间内得到栈的最大或者最小值
- 元素函数编程之美系列之栈和队列1—在O(1)的时间内得到栈的最大或者最小值
- mysql group by分组,根据一个字段分组 ,又想得到另一个字段的最大或者最小。如何解决。
- 使用R语言得到向量中所有的最大值或者最小值的下标
- 栈和队列(8)-- 最大值减去最小值小于或者等于num的子数组
- layui设置日期最大值或者最小值为当前时间
- datePicker时间控件最大日期、最小日期设置
- php自定义队列--获取最大或最小
- SQL 获取当前月的第一天最后一天获取当月最大最小的时间当月天数,当月第一天,当月最后一天
- UVA 10714-Ants(求花费的最大最小时间)
- 如何实现具有最大值、最小值和中间值的栈和队列
- 【字符串排序】n个数连接得到最小或最大的多位整数
- 随笔:实现一个队列,使得取出最大值的时间复杂度较低
- ----------------------------MSSQL多列取最大或者最小值---------------
- 在一个数组中查找最大的K个元素或者最小的K个元素
- sql中获取最大和最小时间
- 用最小的比较次数来得到,最大值和最小值
- n个数连接得到最小或最大的多位整数(携程)
- 定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素。要求函数min、push以及pop的时间复杂度都是O(1)。
- 单调队列之最大最小成员