如何实现具有最大值、最小值和中间值的栈和队列

【数据结构】实现栈-输出最大值,最小值,时间复杂度O(1) @TOC 问题 定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的getMin和最大元素的getMax函数。在该栈中,调用getMin、getMax、push及pop的时间复杂度都是O(1).。 解题思路 用辅助栈记住每次入栈的当前最小值/最大值:在入栈时,往辅助栈中加入当前最小值/最大值;出栈时,辅组栈也出栈一个元素。最小值/最大值从辅助栈中获取栈顶元素。 基础代码实现 import java.util.ArrayList; import java.util.EmptyStackExceptio 阅读详情

转自:http://blog.youkuaiyun.com/yangzhongblog/article/details/12391959#comments

在研究“如何实现具有最大值、最小值和中间值的栈和队列”前,我们先考虑以下问题,然后由此过度到题目问题。

1)如何用两个栈实现队列

2)如何用两个队列实现栈

3)如何实现包含获取最小值函数getMin()的栈

4)如何实现包含获取中间值函数getMedian()的栈

5)如何实现包含获取最小值函数getMin()的队列

1 如何用两个栈实现队列

在研究问题前,我们可以用2个栈模拟一下具体操作过程,可以总结出以下规律:

入队:元素插入stack1;

出队:如果stack2中为空,先将stack1中元素入栈stack2,然后再将stack2的栈顶元素出栈。否则直接将stack2中元素出栈。

队列为空:stack1和stack2同时为空

队列大小:为stack1和stack2大小之和

具体过程见下图(图来自《剑指offer》)


Java实现代码如下

[java]  view plain copy
  1. public class QueueByStack<E extends Comparable<E>>  {  
  2.       
  3.     private LinkedList stack1=null;  
  4.     private LinkedList stack2=null;  
  5.       
  6.     //constructor  
  7.     public QueueByStack(){  
  8.         stack1=new LinkedList();  
  9.         stack2=new LinkedList();  
  10.     }//end QueueByStack  
  11.           
  12.     public void insert(E e){  
  13.           stack1.addLast(e);  
  14.     }//end insert()  
  15.       
  16.     public E remove(){  
  17.         if(!isEmpty()){  
  18.             if(stack2.isEmpty()){  
  19.                 stack1Tostack2();  
  20.             }//end if  
  21.   
  22.             return (E)stack2.removeLast();  
  23.         }//end if  
  24.         else{  
  25.             System.out.println("queue is empty");  
  26.             return null;  
  27.         }//end else  
  28.     }//end remove  
  29.       
  30.     //将stack1中元素入栈stack2  
  31.     private void stack1Tostack2(){  
  32.         while(!stack1.isEmpty()){  
  33.             stack2.addLast(stack1.removeLast());  
  34.         }//end while      
  35.     }//end stack1ToStack2()  
  36.       
  37.     public boolean isEmpty(){  
  38.         return stack1.isEmpty() && stack2.isEmpty();  
  39.     }//end isEmpty()  
  40.       
  41.     public int size(){  
  42.         return (stack1.size()+stack2.size());  
  43.     }//end size()  
  44.   
  45.     /** 
  46.      * @param args 
  47.      */  
  48.     public static void main(String[] args) {  
  49.         QueueByStack q=new QueueByStack();  
  50.         q.insert(1);  
  51.         q.insert(2);  
  52.         q.insert(3);  
  53.         System.out.println(q.remove());  
  54.         System.out.println(q.remove());  
  55.         q.insert(4);  
  56.         System.out.println(q.remove());  
  57.         System.out.println(q.remove());  
  58.     }  
  59. }  

2 如何用两个队列实现栈

还是先用2个队列模拟栈的出栈和入栈过程,可以得出以下规律:

入栈:压入非空的那个队列

出栈:将非空队列中的n-1个元素压入空的队列中,然后将第n个元素出栈。

具体过程见下图(图来自《剑指offer》)


3 如何实现包含获取最小值函数的栈

问题:定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的getMin函数。在该栈中,调用getMin、push及pop的时间复杂度都是O(1).

思路:用一个辅助栈stack2记住每次入栈stack1的当前最小值:在stack1入栈时,往stack2中加入当前最小值;stack1元素出栈时,stack2也出栈一个元素。最小值从stack2中获取及栈顶元素。

4 如何实现包含获取中间值函数的栈

如果能对栈中元素进行排序,那么排序好的中间值即为所求。问题3和问题4的具体代码如下,代码中同时实现了获取栈的最大值、最小值和中间值

[java]  view plain copy
  1. public class Stack<E extends Comparable<E>> {  
  2.       
  3.     private LinkedList<E> heartStack=new LinkedList<E>();   
  4.     private LinkedList<E> curMinStack=new LinkedList<E>(); //辅助栈,用于记录当前最小值  
  5.     private LinkedList<E> curMaxStack=new LinkedList<E>(); //辅助栈,用于记录当前最大值  
  6.       
  7.     public void push(E e){  
  8.            heartStack.push(e);  
  9.            //当前最小值入栈curMinStack  
  10.            E currentMin=curMinStack.peek();  
  11.            if(currentMin.compareTo(e)>0){  
  12.                curMinStack.push(e);  
  13.            }//end if  
  14.            else  
  15.                curMinStack.push(currentMin);  
  16.              
  17.            //当前最大值入栈curMinStack  
  18.            E currentMax=curMinStack.peek();  
  19.            if(currentMax.compareTo(e)<0){  
  20.                curMaxStack.push(e);  
  21.            }//end if  
  22.            else  
  23.                curMaxStack.push(currentMax);  
  24.     }//end push()  
  25.       
  26.     public E pull(){  
  27.         if(isEmpty())  
  28.             return null;  
  29.         else{  
  30.             E e=heartStack.poll();  
  31.             curMinStack.poll();  
  32.             curMaxStack.poll();  
  33.             return e;  
  34.         }//end else  
  35.     }//end pull()  
  36.       
  37.     public E getMax(){  
  38.         return curMaxStack.peek();  
  39.     }//end getMax()  
  40.       
  41.     public E getMin(){  
  42.         return curMinStack.peek();  
  43.     }//end getMin()  
  44.       
  45.     public int size(){  
  46.         return heartStack.size();  
  47.     }//end size()  
  48.       
  49.     public boolean isEmpty(){  
  50.         return heartStack.isEmpty();  
  51.     }//end isEmpty()  
  52.       
  53.     public E getMedian(){  
  54.         E[] e=(E[]) heartStack.toArray();  
  55.         Arrays.sort(e);  
  56.         return e[e.length/2];  
  57.     }//end getMedian()  
  58.       
  59.     public E[] toArray(){  
  60.         return (E[])heartStack.toArray();  
  61.     }//end toArray()  
  62. }  

5 如何实现包含获取最小值函数的队列

问题:定义队列的数据结构,请在该类型中实现一个能够得到队列的最小元素的getMin函数。在该队列中,调用getMin、insert及remove的时间复杂度都是O(1).

思路1:用最小堆实现优先队列,获取最小值时间复杂度为O(nlogn),但优先队列只能获取最小值,remove获取的不是先入队的元素。

思路2:

如果能用栈有效地实现队列,而栈的获取最小值的操作又很容易实现,那么队列的获取最小值的操作也很容易完成。

因为上面可用2个栈实现栈的min函数,而用2个栈可以实现队列。所以可以用已实现了获取最小值的栈stack1和stack2实现队列,而整个队列的最小值从min(stack1.getMin(),stack2.getMin())中获取。具体实现代码见问题6中代码。

6 如何实现具有最大值、最小值和中间值的栈和队列

问题5解决了用O(1)时间获取栈的最小值,那么解决最大值的问题也迎刃而解。对于获取队列的中间值,可以将队列中所有元素排序,然后获取排序后的中间值。

具体实现如下(代码中的stack类为上述问题4中已实现的可以获取最大值和最小值的栈):

[java]  view plain copy
  1. public class ExmaPeekableQueue<E extends Comparable<E>>  implements IExamPeekableQueue{  
  2.     Stack stack1=new Stack();  
  3.     Stack stack2=new Stack();  
  4.       
  5.     @Override  
  6.     public void enqueue(Comparable e) {  
  7.         stack1.push(e);       
  8.     }//end enqueue()  
  9.   
  10.     @Override  
  11.     public Comparable<E> dequeue() {  
  12.         if(stack2.isEmpty()){  
  13.             stack2.push(stack1.pull());  
  14.         }//end if  
  15.           
  16.         return stack2.pull();  
  17.     }//end dequeue()  
  18.   
  19.     @Override  
  20.     public Comparable<E> peekMedian() {  
  21.         Comparable[] arr=null; //用于存储队列中当前元素的数组  
  22.           
  23.         if(stack1.isEmpty()){  
  24.             arr=stack2.toArray();  
  25.         }//end if  
  26.         else if(stack2.isEmpty()){  
  27.             arr=stack1.toArray();  
  28.         }//end if  
  29.         else{  
  30.             arr=new Comparable[size()];  
  31.             Comparable[] arrE1=stack1.toArray();  
  32.             Comparable[] arrE2=stack2.toArray();  
  33.               
  34.             //将2个栈中的元素复制到一个数组中  
  35.             int i=0;  
  36.             for(;i<stack1.size();i++){  
  37.                 arr[i]=arrE1[i];  
  38.             }//end for  
  39.               
  40.             for(int j=0;j<stack2.size();j++){  
  41.                 arr[++i]=arrE2[j];  
  42.             }//end for  
  43.         }//end else  
  44.               
  45.         Arrays.sort(arr);  
  46.         return arr[arr.length/2];  
  47.     }//end peekMedian()  
  48.   
  49.     @Override  
  50.     public Comparable peekMaximum() {  
  51.         Comparable max1=stack1.getMax();  
  52.         Comparable max2=stack2.getMax();  
  53.           
  54.         if(max1.compareTo(max2)>0){  
  55.             return max1;  
  56.         }//end if  
  57.         else  
  58.             return max2;  
  59.     }  
  60.   
  61.     @Override  
  62.     public Comparable<E> peekMinimum() {  
  63.         Comparable min1=stack1.getMin();  
  64.         Comparable min2=stack2.getMin();  
  65.           
  66.         if(min1.compareTo(min2)>0){  
  67.             return min2;  
  68.         }//end if  
  69.         else  
  70.             return min1;  
  71.     }//end peekMinimum()  
  72.   
  73.     @Override  
  74.     public int size() {  
  75.         return (stack1.size()+stack2.size());  
  76.     }//end size()  
  77. }//end class  
快速排序的非递归算法(使用队列) 前些天学习了程序栈空间的大小是会有上限的。看来递归的算法永远无法应用到大规模的数据上,毕竟栈空间有限。这几天写了点算法题目,刚好涉及到如何广度优先搜索。想起自己学数据结构的时候就想快排能否以非递归式方式实现。于是自己就写了个非递归的快排算法,以供学习。   我搜了一下网上的快排非递归算法,几乎都是使用栈来模拟的。但其实完全不必使用栈,队列一样可以。一开始觉得栈可能消耗最大空间比队列少一点,但其实 阅读详情

相关推荐

平台跳跃游戏中的自动寻路,与地图导航扩展

平台游戏:主要的游戏方式是在2D平面上使用各种方式在悬浮平台上进行移动和穿过各种障碍。 现如的平台游戏中的平台特性与种类是很多的,像马里奥(FC)的单向支撑不可穿透的,或魂斗罗(FC)单向支撑可穿透的… \ 超级玛丽 魂斗罗 空洞骑士 蔚蓝 本博文 支撑 上 上 上 左、上、右 上 穿透 无 上、下 无 上(部分) 上下 所以本文主要以向上支撑并上下穿透的平台特性来进行实现 需求分析 在关卡设计后,地形的数据需要自动识别 地形中的平台可上下穿透移动,并可向上站立 平台的移动路..

MOV的博客 3062

【数据结构】关于堆栈等数据结构的问题

1 在栈基础上完成取中位数,最大最小数的操作  想到了流中位数和这个类似。 来考虑求取堆栈中中间值的方法。受求最大值、最小值方法的启发,设计出求中间值的方法。求中间值得方法需要两个栈,即最大值栈leftMax和最小值栈rightMin,还需要一个存中间值的数据结构,结构如下:   Median:存放中间值;leftCount:小于中间值元素的个数;rightCoun

一地鸡毛 1115

OpenMV识别颜色源码

【代码】OpenMV识别颜色源码。

dxt258013的博客 403

C++使用两个栈实现一个可以获取栈中最大值和最小值的栈

#include #include struct stack_pro { std::stack stk_data; std::stack stk_min; }; void push(stack_pro &stk, const int &num); void pop(stack_pro &stk, int & tag); void getmin(stack_pro

Code to Prose 3129

k-shape时间序列聚类实战:从理论到tslearn实现

本文深入探讨了k-shape时间序列聚类算法,从核心原理到tslearn库的实战应用。k-shape通过标准化互相关系数衡量序列形状相似性,专注于识别波动模式而非绝对数值。文章详细介绍了算法流程、Python环境搭建、数据预处理、最佳K值确定方法,并通过完整代码示例展示了模型训练与结果可视化,帮助读者掌握这一强大的“形状捕手”工具。

weixin_29061465的博客 174

别再死记硬背HJB方程了!用Python数值求解一个简单最优控制问题(附完整代码)

本文通过Python数值求解Hamilton-Jacobi-Bellman(HJB)方程,帮助读者从工程实践角度理解最优控制问题。教程涵盖从建立简单车辆控制模型到离散化HJB方程、实现值迭代算法及可视化结果的完整流程,适合具备Python基础的开发者学习。

weixin_42520796的博客 371

Java实现-队列中取最大值操作

class MyQueue{ MyStack myStack1=new MyStack(); MyStack myStack2=new MyStack(); public void offer(int value){ myStack1.push(value); } public int poll(){ if(myStack2.isEmpty()){ while(!m

Narasimha_Karumanchi 2436

避坑指南:在Ubuntu 22.04上配置UR5e与ROS2 Humble真机通信的完整流程

本文详细介绍了在Ubuntu 22.04上配置UR5e机械臂与ROS2 Humble真机通信的完整流程,包括环境准备、网络配置、URCap安装、ROS2驱动部署及控制器状态验证等关键步骤。特别针对常见问题如网络连接失败、驱动启动错误等提供了实用解决方案,帮助工程师高效完成UR5e与ROS2的集成工作。

weixin_30790841的博客 463

有趣的题目系列一:实现具有最大值、最小值、中间值的栈和队列

题目来源: 1)http://blog.youkuaiyun.com/bigheadzzy/article/details/8002253 2)http://blog.youkuaiyun.com/yangzhongblog/article/details/12391959 文章中的大部分题目描述、代码均参考自上面二处,加以自己的一些理解。 ------------------------------------

1ouis的专栏 1590

C51:PWM+舵机角度控制

PWM,英文名Pulse Width Modulation,是脉冲宽度调制缩写,它是通过对一系列脉冲的宽度进行调制,等效出所需要的波形(包含形状以及幅值),对模拟信号电平进行数字编码,也就是说通过调节占空比的变化来调节信号、能量等的变化,占空比就是指在一个周期内,信号处于高电平的时间占据整个信号周期的百分比,例如方波的占空比就是50%.脉冲宽度调制通过占空比编码模拟信号一个周期内,高电平占据时长的百分比如下图所示,最便宜的舵机sg90,常用三根或者四根接线,黄色为PWM信号控制。

qq_73379310的博客 3388

从数据库到数据仓库:数据仓库导论

本文为数据仓库导论,旨在介绍数据仓库的基本理念和应用场景,帮助读者理解数据仓库的重要性及其在企业中的实际应用。

探索大数据世界 - 深入解析数据存储、分布式计算与人工智能 2784

实现O(1)获取最大最小值的栈----java

实现O(1)获取最大最小值的栈和队列----java 一.如何实现包含获取最小值函数的栈 问题:定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的getMin函数。在该栈中,调用getMin、push及pop的时间复杂度都是O(1). 最小值思路:用一个辅助栈stack2记住每次入栈stack1的当前最小值:在stack1入栈时,往stack2中加入当前最小值;st

毛毛虫的小哈 1万+

已解决“TimeouEror [WinEror 10060由于连接方在一段时间后没有正确答复 或连接的主机没有反应,连接尝试失败“,亲测有效!!!

已解决"TimeouEror [WinEror 10060由于连接方在一段时间后没有正确答复 或连接的主机没有反应,连接尝试失败",亲测有效!!!

wbajsjhhhhh的博客 1万+

栈和队列

转载于: http://www.jliae.edu.cn/jsj/datastructure/test4.htm   4-1 改写顺序栈的进栈成员函数Push (x ),要求当栈满时执行一个stackFull ( )操作进行栈满处理。其功能是:动态创建一个比原来的栈数组大二倍的新数组,代替原来的栈数组,原来栈数组中的元素占据新数组的前MaxSize位置。 【解答】templatevoid s

我为编程狂,我为外语狂 9984

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

java获取栈最大值_实现O(1)获取最大最小值的栈----java

实现O(1)获取最大最小值的栈和队列----java一.如何实现包含获取最小值函数的栈问题:定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的getMin函数。在该栈中,调用getMin、push及pop的时间复杂度都是O(1).最小值思路:用一个辅助栈stack2记住每次入栈stack1的当前最小值:在stack1入栈时,往stack2中加入当前最小值;stack1元素出栈时,stac...

weixin_39717152的博客 468

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

java 获取最小值_实现O(1)获取最大最小值的栈----java

实现O(1)获取最大最小值的栈和队列----java一.怎样实现包括获取最小值函数的栈问题:定义栈的数据结构,请在该类型中实现一个可以得到栈的最小元素的getMin函数。在该栈中,调用getMin、push及pop的时间复杂度都是O(1).最小值思路:用一个辅助栈stack2记住每次入栈stack1的当前最小值:在stack1入栈时,往stack2中增加当前最小值;stack1元素出栈时,stac...

weixin_36434922的博客 419

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

leetcode-单调栈/单调队列

接雨水 https://blog.youkuaiyun.com/meng_xin_true/article/details/108136941

MaYingColdPlay的博客 989

西门子smart200 平均值,最新有图片证明中值,最大值,最小值,排序,数据连续移位。 2个...

老规矩,先看效果再拆解代码。中位值计算经过排序后取中间值的操作,在波动数据中能有效过滤突发干扰。2个版本,一个整数版本,一个浮点数版本,自己定义数据区间范围,采用指针算法,自己可以组合,作为一些数据处理。2个版本,一个整数版本,一个浮点数版本,自己定义数据区间范围,采用指针算法,自己可以组合,作为一些数据处理。西门子smart200 平均值,最新有图片证明中值,最大值,最小值,排序,数据连续移位。西门子smart200 平均值,最新有图片证明中值,最大值,最小值,排序,数据连续移位。

vmnfPZtzOv的博客 284

java旋转数组最大值,「算法」旋转数组的最小数字

0006 旋转数组的最小数字题目描述把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。例如: 数组 {3,4,5,1,2} 为 {1,2,3,4,5} 的一个旋转,该数组的最小值为1。说明:给出的所有元素都大于0,若数组大小为0,请返回0。题目地址解题报告直接查找本题解由微信公众号小猿刷题提供, 错误之处, 欢迎指正.在两...

weixin_32666923的博客 464

栈之:【维护序列前i个前缀和的最小值和最大值】【开两个栈,一个栈维护另外一个栈的状态值】

【代码】栈之:【维护序列前i个前缀和的最小值和最大值】【开两个栈,一个栈维护另外一个栈的状态值】

bei2002315的博客 227

LeetCode 1825 求出MK平均值【Set 队列】 HERODING的LeetCode之路

好久没更新力扣困难题的题解了,今天这道困难题有点意思,读罢题目一目了然,解题思路清晰明了,就是解题过程细节满满。这是一个数据流场景的问题,保留最后m个元素,但是要去除k个最大,k个最小,返回平均值。其中第6步骤非常巧妙,因为数据流中的元素重复,在删除阶段可能会把后来的相同的数删除,那么我们只要保证后来的相同的数在s2中,最后才删s2,这就保证了先来的相同的元素一定会在s1或者s3中先删除,即使s2中有多个重复也不影响最终结果(但是在s1或s3中会影响)。

HERODING23的博客 771
上一篇: Bloom Filter概念和原理
下一篇: Java虚拟机原理、内存分配和回收机制
louis9212
博客等级 码龄14年 8粉丝 49原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值