标签:min 需要 包含 width 建议 pop top new test
左程云的《程序员代码面试指南》,第一个题是“设计一个有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完全没有存在的必要,所以建议使用单栈来实现,不要使用双栈了,不仅麻烦,而且还多费一些空间;
使用单栈也比较简单,原理如下所示:

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
}
}
标签:min 需要 包含 width 建议 pop top new test
原文地址:https://www.cnblogs.com/-beyond/p/13227736.html