package questions;
import java.util.ArrayList;
/**
* @title 设计包含min函数的栈[数据结构]<br>
* @question 定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素。要求函数min、push以及pop的时间复杂度都是O(1)<br>
* @analysis 分析:这是去年google的一道面试题。
*
* 我看到这道题目时,第一反应就是每次push一个新元素时,将栈里所有逆序元素排序。这样栈顶元素将是最小元素。
* 但由于不能保证最后push进栈的元素最先出栈,这种思路设计的数据结构已经不是一个栈了。
*
* 在栈里添加一个成员变量存放最小元素(或最小元素的位置)。每次push一个新元素进栈的时候,如果该元素比当前的最小元素还要小,
* 则更新最小元素。
*
* 乍一看这样思路挺好的。但仔细一想,该思路存在一个重要的问题:如果当前最小元素被pop出去,如何才能得到下一个最小元素?
*
* 因此仅仅只添加一个成员变量存放最小元素(或最小元素的位置)是不够的。我们需要一个辅助栈。每次push一个新元素的时候,同时将最小元素(
* 或最小元素的位置
* 。考虑到栈元素的类型可能是复杂的数据结构,用最小元素的位置将能减少空间消耗)push到辅助栈中;每次pop一个元素出栈的时候
* ,同时pop辅助栈
* @author Sam
*
*/
public class Ex1o2o3 {
public static void main(String[] args) {
MinStack stack = new MinStack();
stack.push(3);
stack.print();
stack.push(4);
stack.print();
stack.push(2);
stack.print();
stack.push(1);
stack.print();
stack.pop();
stack.print();
stack.pop();
stack.print();
stack.push(0);
stack.print();
}
}
class MinStack {
private ArrayList<Integer> dataStack;// 不使用List在取min时虽然给index但需要算
private ArrayList<Integer> minStack;// store the position of Min Element
public MinStack() {
dataStack = new ArrayList<Integer>();
minStack = new ArrayList<Integer>();
}
public void push(int item) {
if (isEmpty()) {
dataStack.add(item);
minStack.add(0);
} else {
dataStack.add(item);
int minIndex = minStack.get(minStack.size() - 1);
int min = dataStack.get(minIndex);
if (min > item) {
minStack.add(dataStack.size() - 1);
} else {
minStack.add(minIndex);
}
}
}
public int pop() {
int top = -1;
if (isEmpty()) {
System.out.println("no element,no pop");
} else {
minStack.remove(minStack.size() - 1);
top = dataStack.remove(dataStack.size() - 1);
}
return top;
}
public int min() {
if (isEmpty()) {
return -1;
}
int minIndex = minStack.get(minStack.size() - 1);
return dataStack.get(minIndex);
}
public void print() {
System.out.println("数据栈\t辅助栈\t最小值");
for (int i = 0; i < dataStack.size(); i++) {
System.out.println(String.format("%d\t%d\t%d", dataStack.get(i),
minStack.get(i), min()));
}
}
public boolean isEmpty() {
return 0 == dataStack.size();
}
}
输出结果:
数据栈 辅助栈 最小值
3 0 3
数据栈 辅助栈 最小值
3 0 3
4 0 3
数据栈 辅助栈 最小值
3 0 2
4 0 2
2 2 2
数据栈 辅助栈 最小值
3 0 1
4 0 1
2 2 1
1 3 1
数据栈 辅助栈 最小值
3 0 2
4 0 2
2 2 2
数据栈 辅助栈 最小值
3 0 3
4 0 3
数据栈 辅助栈 最小值
3 0 0
4 0 0
0 2 0