实现单栈实现支持getMin的栈
Posted -beyond
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实现单栈实现支持getMin的栈相关的知识,希望对你有一定的参考价值。
双栈实现getMin功能的问题
左程云的《程序员代码面试指南》,第一个题是“设计一个有getMin功能”的栈,思路如下:
用到了双栈:
一个栈(stackData)用来保存当前栈中的元素,其功能和正常的栈没有区别;
另外一个栈(stackMin)用来保存每一步的最小值;
2种方案思路就是下面这幅图所示:
如果使用上面图中的数据,其实发现不了什么问题,但是可以进行如下操作:
getMin(); // 返回1 // 直接从stackMin中获取栈顶元素,就是栈的最小值(1),正确 pop(); // stackData弹出1,同时stackMin中的栈顶元素所有1,然后stackMin栈顶元素为3,无异常 top(); // 返回2 // 从stackData获取栈顶元素(不出栈) getMin(); // 返回3 // 从stackMin返回栈顶元素,但是返回的是3,而不是2,因为stackData的最小元素是2
所以,书中的方案,并不能实现正确getMin功能,另外,如果换一组数据:0、1、0,画出的图如下:
对于是上面的两个图,进行如下操作:
getMin(); // 返回0 正确 top(); // 返回0 正确 pop(); // stackData的栈顶元素0出栈,同时,stackMin的所有元素都会出栈 // 因为stackMin栈顶元素始终和stackData出站的元素相同,都为0 top(); // 返回1 正确 getMin(); // 出现异常,因为stackMin已经是个空栈了 // 预期是返回0,因为stackData的栈底元素是0,比top元素小
其实对于上面这个问题,也可以这样修改:
1.stackData仍旧保持不变;
2.stackMin中不是只存一个int,而是存一个Item;
3.Item有两个域,一个data域,表示本次push的值,另一个是min,表示push当前这个值后,stackData的最小值。
原理如如下所示:
其实,看了上面这个双栈,你会发现,stackData是多余的,因为stackMin中已经包含了所有需要的数据,stackData完全没有存在的必要,所以建议使用单栈来实现,不要使用双栈了,不仅麻烦,而且还多费一些空间;
单栈实现getMin功能
使用单栈也比较简单,原理如下所示:
Java实现代码如下:
package cn.ganlixin.ds; import java.util.Stack; class Item { // 每次push的值 int data; // data入栈后,栈的最小值 int min; public Item(int data, int min) { this.data = data; this.min = min; } } public class MinStack { //存放元素的栈 private Stack<Item> stack = null; public MinStack() { stack = new Stack<>(); } public void push(int x) { // 栈为空,则push进来的x就是最小值 if (stack.isEmpty()) { stack.push(new Item(x, x)); } else { // 获取栈顶元素,因为栈顶元素的min保存了push x之前的最小值 Item top = stack.peek(); // 如果栈顶元素的最小值比当前x要小,则新Item的min为top.min stack.push(new Item(x, top.min > x ? x : top.min)); } } public void pop() { stack.pop(); } public int top() { return stack.peek().data; } public int getMin() { return stack.peek().min; } }
测试:
public class TestMinStack { @Test public void test() { MinStack minStack = new MinStack(); minStack.push(0); minStack.push(1); minStack.push(0); System.out.println(minStack.getMin()); // 0 minStack.pop(); System.out.println(minStack.top()); // 1 System.out.println(minStack.getMin()); // 0 } }
以上是关于实现单栈实现支持getMin的栈的主要内容,如果未能解决你的问题,请参考以下文章