【算法刷题】C01-Q01 设计一个有getMin功能的栈
C01-Q01 设计一个有getMin功能的栈
参考:《程序员代码面试指南》第1章第1题
题目要求
实现一个特殊的栈,在实现栈的基本功能的基础上,再实现返回栈中最小元素的操作。
- pop、push、getMin 操作的时间复杂度都是 O(1)。
- 设计的栈类型可以使用现成的栈结构。
个人解法
【思路】
用2个栈,一个普通的先进后出的栈stack,另一个栈minStack用于存迄今为止的最小值,当pop或者push的时候,将元素与minStack栈顶元素进行比较,小于等于就放进minStack。
【Tips】
获取minStack栈顶元素时,需要先判断栈是否为空,否则会抛异常
【结果】
执行用时:8 ms, 在所有 Java 提交中击败了29.51% 的用户
内存消耗:40.1 MB, 在所有 Java 提交中击败了68.38% 的用户
【Code】
class MinStack1 {
private Stack<Integer> stack;
private Stack<Integer> min;
public MinStack1() {
stack = new Stack<>();
min = new Stack<>();
}
public int pop() {
Integer e = stack.pop();
if (e.equals(min.peek())) {
min.pop();
}
return e;
}
public int top() {
return stack.peek();
}
public void push(int e) {
stack.push(e);
if (min.isEmpty()) {
min.push(e);
return;
}
if (e <= min.peek()) {
min.push(e);
}
}
public int getMin() {
return min.peek();
}
}
优秀解法
【思路】
用1个栈实现,每次插入一个数字对{n,min}。例如:插入2时就是{2,2},插入1时就是{1,1},插入3时就是{3,1}
【结果】
执行用时:6 ms, 在所有 Java 提交中击败了95.98% 的用户
内存消耗:39.8 MB, 在所有 Java 提交中击败了97.24% 的用户
【Code】
class MinStack2 {
private Stack<int[]> stack;
public MinStack2() {
stack = new Stack<>();
}
public int pop() {
return stack.pop()[0];
}
public int top() {
return stack.peek()[0];
}
public void push(int e) {
if (stack.isEmpty()) {
stack.push(new int[]{e, e});
return;
}
int min = Math.min(e, stack.peek()[1]);
stack.push(new int[]{e, min});
}
public int getMin() {
return stack.peek()[1];
}
}
测试代码
@Test
public void testMinStack1() {
MinStack1 stack = new MinStack1();
stack.push(2);
assert stack.getMin() == 2;
stack.push(3);
assert stack.getMin() == 2;
stack.push(1);
assert stack.getMin() == 1;
stack.push(4);
assert stack.getMin() == 1;
assert stack.pop() == 4;
assert stack.getMin() == 1;
assert stack.pop() == 1;
assert stack.getMin() == 2;
}
@Test
public void testMinStack2() {
MinStack2 stack = new MinStack2();
stack.push(2);
assert stack.getMin() == 2;
stack.push(3);
assert stack.getMin() == 2;
stack.push(1);
assert stack.getMin() == 1;
stack.push(4);
assert stack.getMin() == 1;
assert stack.pop() == 4;
assert stack.getMin() == 1;
assert stack.pop() == 1;
assert stack.getMin() == 2;
}