题目
定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的min函数。在该栈中,调用min、push及pop的时间复杂度为O(1)。
思路
对于栈类型的数据结构来说,它的push和pop的时间复杂度是O(1),所以这里主要要考虑的是min方法。
思路一:
每次入栈的时候,将栈里所有的元素进行排序,让最小的元素位于栈顶,这样就能在O(1)时间得到最小元素了。但是这种思路不能保证最后入栈的元素最先出栈,因此这样的数据结构已经不是栈了。
思路二:
需要在栈结构中使用一个成员变量,此成员变量用来记录最小的元素。每次入栈的时候,需要将入栈的元素与此成员变量比较,保证成员变量中的值是栈中的最小元素,这样就可以以O(1)的时间复杂度来找出栈中的最小元素,但是那问题来了:如果当前最小的元素被弹出去了,那么如何以O(1)的时间复杂度弹出下一个最小的元素呢?
思路三:
采用空间换时间的策略,使用一个辅助栈。每次入栈的时候,都会在辅助栈中添加一个数据,此数据的值就是目前栈中的最小值。
例如:将数据{1,2,3}压入栈中,之后连续弹出两次,再向栈中压入数据0,具体的栈中以及辅助栈中的数据如下:
相比较而言,思路三符合题意。
代码实现
public class Stack{
private int[] mArray;
private int[] fArray;
private int items;
private int min;
public Question021(int size) {
mArray = new int[size];
fArray = new int[size];
items = 0;
}
public boolean isFull() {
return items == mArray.length;
}
public boolean isEmpty() {
return items == 0;
}
public void push(int item) {
if (isEmpty()) {
min = item;
mArray[items] = item;
fArray[items] = min;
items++;
} else if (!isFull()) {
min = min < item ? min : item;
mArray[items] = item;
fArray[items] = min;
items++;
}
}
public int pop() {
if (!isEmpty()) {
return mArray[--items];
} else {
throw new ArrayIndexOutOfBoundsException();
}
}
public int min() {
if (!isEmpty()) {
return fArray[items-1];
} else {
throw new ArrayIndexOutOfBoundsException();
}
}
}