问题
如何设计一个栈,使得getMinimum()操作的时间复杂度为O(1)
解答
设计一个辅助栈保存原栈中所有元素的最小值,并且,假设(辅助)栈中每个元素的值都比它下面的元素小,为了简单起见,原栈称为main stack,辅助栈称为minStack
当mainStack中的元素出栈时,minStack的元素也跟着出栈,当mainStack中有新元素入栈时,其与当前
最小值进行比较,取其中的最小值入minStack,如果需要获取最小值,只需要获取minStack栈顶元素,
以下面的问题为例:
初始时,假设2,6,4,1,5依次入栈,按照上述算法,执行步骤如下:
代码
- 栈结构
/**
* 基于链表的栈的实现
*/
public class LinkedListStack {
private ListNode head = null;
public LinkedListStack() {
head = new ListNode(0);
}
public void push(int data) {
if (head == null) {
head = new ListNode(data);
} else if (head.getData() == 0) {
head.setData(data);
} else {
ListNode node = new ListNode(data);
node.setNext(head);
head = node;
}
}
public int pop() {
if (head == null) {
throw new EmptyStackException();
} else {
int data = head.getData();
head = head.getNext();
return data;
}
}
public int top() {
if (head == null) {
return 0;
} else {
return head.getData();
}
}
public boolean isEmpty() {
return head == null;
}
public void deleteStack() {
head = null;
}
}
- 算法实现
/**
* 如何设计栈,使得获取栈最小值的时间复杂度为O(1)
*/
public class AdvancedStack {
private LinkedListStack elementStack = new LinkedListStack();
private LinkedListStack minStack = new LinkedListStack();
public void push(int data) {
elementStack.push(data);
if (minStack.isEmpty() || minStack.top() >= data) {
minStack.push(data);
} else {
minStack.push(minStack.pop());
}
}
public int pop() {
if (elementStack.isEmpty()) {
throw new RuntimeException("Stack is Empty!");
}
minStack.pop();
return elementStack.pop();
}
public int getMinmum() {
if (minStack.isEmpty()) {
throw new RuntimeException("Stack Is Empty!");
} else {
return minStack.top();
}
}
public int top() {
return elementStack.pop();
}
public boolean isEmpty() {
return elementStack.isEmpty();
}
}