您的位置:首页 > 其它

No2、设计包含 min 函数的栈(栈)

2013-02-28 14:38 225 查看
定义栈的数据结构,要求添加一个 min 函数,能够得到栈的最小元素。要求函数 min、push 以及 pop 的时间复杂度都是 O(1)。编程之美上有一道跟这个题比较类似的题目,但那道题是要实现函数 max、push 以及 pop 的时间复杂度都是 O(1)的一个队列,那个队列就是用本题中的栈组织成的。思考如下:首先想到的是在栈中设置一个成员变量为min,保存栈的最小元素。min的时间复杂度是o(1),push()的时候比较添加进的元素和min中的大小,更新min,时间复杂度也是o(1);但是在pop()的时候问题出现了,如果pop操作时把当前栈中最小值弹出栈了,只能遍历剩下的元素才能更新正确的min。ok,问题来了。我们重新回顾一下推入栈的过程,假如当前栈的最小值是a,新加入栈的数是b,b<a,那么min=b;如果在某一次pop,a被pop出去了,那么栈的最小值就是b,也就是该元素将要添加进栈(还未添加进栈)的时候的最小值,我们需要保存一个变量才存储这个值的索引。所以解决方法来了,在栈的元素的定义中,添加一个成员变量pre,它代表该元素将要添加进栈(还未添加进栈)的时候的最小值在栈中的位置。在push过程,如果新的元素小于当前栈中最小值,pre设置为当前栈最小值的索引,更新栈中的minIndex和min;如果新的元素大于当前栈中最小值,pre设置为当前栈最小值的索引..(其实pre不需要设置,因为在这种情况下这个元素的存在根本不影响min)在pop过程,如果弹出的元素等于当前栈中最小值,将栈中的minIndex设置为弹出元素的preMin,更新栈中的min,弹出元素;如果弹出的元素大于当前栈中最小值,直接弹出..这个解决方法与设计模式中的备忘录模式有点相近,就是在每个元素中将之前栈的状况给保存起来,然后把元素push进栈;pop该元素的时候,通过里面的数据恢复该元素还未添加进栈的时候栈的状态..关键代码:栈元素定义:
class Element{int data = 0;    //数据int preMin = 0;  //未添加新元素的栈的最小值的索引public Element(int data){this.data = data;}}
栈的定义:
class Stack{private int MAXSIZE = 10;private Element[] elements = new Element[MAXSIZE];private int pos = 0;private int min = Integer.MAX_VALUE;private int minIndex = 0;public boolean push(int num){if(pos >= MAXSIZE)                              //判断栈已满{System.out.println("栈已满!");return false;}Element newE = new Element(num);if(num < min)					//push元素小于当前最小值,更新min;{min = num;newE.preMin = minIndex;minIndex = pos;}elements[pos] = newE;pos++;return true;}public boolean pop(){if(pos == 0){System.out.println("栈为空!");return false;}if(pos == minIndex+1)                        //当pop出当前最小值,更新min;{minIndex = elements[pos-1].preMin;min = elements[minIndex].data;}pos--;return true;}public int min()                   //min函数的定义:{if(pos == 0){System.out.println("栈为空!");return -1;}return min;}}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: