实现一个栈(元素遵守先入后出顺序),能够通过 min 方法在 O(1)时间内获取栈中的最小元素。同时,栈的基本操作:入栈(Push)、出栈(Pop),也是在O(1)时间内完成的

来源:互联网 发布:软件实施管理制度 编辑:程序博客网 时间:2024/05/22 14:53

实现一个栈(元素遵守先入后出顺序),能够通过 min 方法在 O(1)时间内获取栈中的最小元素。同时,栈的基本操作:入栈(Push)、出栈(Pop),也是在O(1)时间内完成的。

此问题可分析为:

方案一:

建立两个栈,一个用来存放插入的数据datastack,一个用来存放最小的数据minstack;当最小栈不为空时,在datastack中插入一个数据,先用一变量tmp来存放minstack栈顶元素,将插入数据与tmp比较,若插入数据小将插入数据拷贝一份push进minstack栈内,若tmp小再压入minstack栈内,依次重复。

方案二:

只用建一个栈,但每push进一个元素,先于原来较小元素比较,若原来小,将原来数据拷贝一份入栈,接着将刚要入栈的的元素入栈,也就是说,每次要push一个元素进去,首先得判断,先入的是较小元素或其拷贝,然后是要入栈的元素。

 数据结构实现:

#include <iostream>  #include<stdlib.h>using namespace std;   #include <stack>   template <class T>  class retmin  {  public :       void pushmin(const T& x)      {           _num.push (x);            if(!_min.empty ())           {               T tmp = _min.top ();                if( x < tmp)               {                   _min.push (x);               }                else                   _min.push (tmp);           }            else               _min.push (x);                 }       void popmin()      {           _num.pop ();           _min.pop ();      }        T Retmin()      {            return _min.top ();      }  private :      stack<T> _num;         stack<T> _min;  };      void Test9()  {      retmin< int> r1;      r1.pushmin (5);      r1.pushmin (4);      r1.pushmin (3);      r1.pushmin (6);      r1.pushmin (1); r1.pushmin (5);      r1.pushmin (4);      r1.pushmin (2);      r1.pushmin (6);      r1.pushmin (1);     cout<<r1.Retmin ()<<endl;  }    int main()  {      Test9(); system("pause");     return 0;  }  

java实现

思路1:添加一个成员变量总是保存当前栈中最小的元素。该思路的实现代码大致是这样的:

复制代码
public class MinStack {        private LinkedList<Integer> stack;    private int min;// save minimum ele of stack        public int pop(){        //check pop minimum ele?    }    public void push(int ele){        //check push minimum ele?    }    public int getMin(){        return min;    }}
复制代码

 

这里就会存在一个问题:保存最小元素的 min 属性 与 栈中的最小元素不一致。

比如:当从栈中 pop 最小元素时,那 min 属性就要 保存 次最小元素了。那如何 找到次最小元素,然后赋值给 min 呢?

 因此,问题的关键就是:当只使用一个 min 属性时,如何保证 min 属性 总是 保存的是当前栈中最小的元素?---即: min 代表的最小元素 要与 栈中的最小元素保存一致。一种方式是当pop出最小元素之后,再遍历栈找出次最小的元素,并将之赋值给 min 。但是,由于遍历使得时间复杂度不再是O(1)

 

思路2:

使用一个辅助栈。此方法能够实现在O(1)时间内获取栈中最小的元素,但是缺点是空间复杂度为O(N)

现在有两个栈:一个是保存元素的数据栈,另一个是辅助栈,辅助栈的栈顶总是 当前数据栈中最小的元素。当Push元素时,首先将该元素Push到数据栈,然后再将该元素与辅助栈的栈顶元素比较:如果该元素比辅助栈的栈顶元素小,则将该元素Push到辅助栈中;否则将辅助栈的栈顶元素再Push到辅助栈中。

比如,现在要Push的元素顺序如下:3,4,2,5....   在数据栈 和 辅助栈中保存的元素如下:

 

三,代码实现

代码中使用了 java.util.LinkedList 类作为 栈的实现。

复制代码
import java.util.LinkedList;public class MinStack {        private LinkedList<Integer> dataStack;    private LinkedList<Integer> minStack;        public MinStack() {        dataStack = new LinkedList<Integer>();        minStack = new LinkedList<Integer>();    }        //base operation    public void push(int ele)    {        dataStack.push(ele);        if(minStack.size() == 0 || ele < minStack.peek())            minStack.push(ele);        else            minStack.push(minStack.peek());    }        public Integer pop(){        if(dataStack.isEmpty())            return null;                assert dataStack.isEmpty() == false && minStack.isEmpty() == false;        int ele = dataStack.pop();        minStack.pop();        return ele;    }        public Integer min(){        if(minStack.isEmpty())            return null;        return minStack.peek();    }        //hapjin test    public static void main(String[] args) {        MinStack stack = new MinStack();                int[] eles = {3,4,2,5};        for (int i : eles) {            stack.push(i);        }        System.out.println(stack.min());//2        System.out.println(stack.pop());//5        System.out.println(stack.pop());//2        System.out.println(stack.min());//3        stack.push(1);        System.out.println(stack.min());    }}
复制代码
0 1
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 头发干枯毛躁怎么办做什么发型 学校不给转学籍怎么办 结婚证号码错了怎么办 继教学分1类不够怎么办 猫咪耳螨传染人怎么办 ph值低了怎么办呀 水的ph值高怎么办 宝宝起热痱子了怎么办 宝宝热的起痱子怎么办 吃了有农药的菜怎么办 水银吃到肚子里怎么办 牙齿有牙结石怎么办可以去除 刷牙牙结石掉了怎么办 痘痘留下的黑印怎么办 脸上用了激素药怎么办 激素药膏用多了怎么办 8岁儿童牙齿不齐怎么办 两个牙齿之间有缝隙怎么办 蛀牙就剩牙根了怎么办 牙龈发白像烂了怎么办 3岁宝宝牙龈肿痛怎么办 1岁宝宝牙龈肿痛怎么办 牙疼引起的发烧怎么办 2岁小儿牙龈红肿怎么办 宝宝出牙牙龈红肿怎么办 3岁宝宝牙龈红肿怎么办 1岁宝宝牙龈红肿怎么办 4岁宝宝牙龈红肿怎么办 儿童牙黑了怎么办啊 牙黑了掉了一块怎么办 1岁幼儿牙齿腐蚀怎么办 我的大牙变黑了怎么办 牙齿里面黑了疼怎么办 最里面的牙黑了怎么办 牙龈的肉裂开了怎么办 有蛀牙怎么办可以变好么 拔智齿没拔干净怎么办 蛀牙只剩牙根了怎么办 牙掉的就剩牙根怎么办 蛀牙牙冠都掉了怎么办 拔智齿断了牙根怎么办