开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第4天,点击查看活动详情
题目描述
设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
实现 MinStack 类:
MinStack() 初始化堆栈对象。
void push(int val) 将元素 val 推入堆栈。
void pop() 删除堆栈顶部的元素。
int top() 获取堆栈顶部的元素。
int getMin() 获取堆栈中的最小元素。
思路
通过两个栈来实现,一个栈 stack 就是正常的栈,另一个栈 minStack 用来保存每一步的最小值,这样子 getMin 就直接返回 minStack 栈顶的元素即可
做法一
stack 每次压入一个元素,最小栈也压入一个元素,弹出的时候 minStack 跟随 stack 弹出即可
-
压入元素
- 压入 stack 中
- 把当前 minStack 中的数据和压入数据进行比较,选最小值压入
-
弹出元素
- 直接把 stack 和 minStack 中的元素都弹出
-
最小值
- 直接弹出 minStack 中的元素
import java.util.Deque;
import java.util.LinkedList;
public class getMin {
public static void main(String[] args) {
Solution stack1 = new Solution();
stack1.push(-2);
stack1.push(0);
stack1.push(-3);
stack1.push(12);
System.out.println(stack1.getMin());
System.out.println(stack1.pop());
stack1.push(-1);
System.out.println(stack1.top());
System.out.println(stack1.pop());
System.out.println(stack1.pop());
System.out.println(stack1.getMin());
}
}
class Solution{
Deque<Integer> stack;
Deque<Integer> minStack;
public Solution(){
stack = new LinkedList<>();
minStack = new LinkedList<>();
minStack.push(Integer.MAX_VALUE);
}
public void push(int val){
stack.push(val);
minStack.push(Math.min(minStack.peek(), val));
}
public int pop(){
if(stack.isEmpty()){
throw new RuntimeException("Stack is empty.");
}
minStack.pop();
return stack.pop();
}
public int top(){
return stack.peek();
}
public int getMin(){
if(minStack.isEmpty()){
throw new RuntimeException("Stack is empty.");
}
return minStack.peek();
}
}
// result
-3
12
-1
-1
-3
-2
做法二
每次压入的时候进行比较,如果小于 minStack 中的最小值就压入,否则不压入,这样子的话,每次弹出的时候就需要比较 minStack 的值与 stack 的 value 是否相等,如果相等就也弹出
import java.util.Deque;
import java.util.LinkedList;
public class getMin {
public static void main(String[] args) {
Solution stack1 = new Solution();
stack1.push(-2);
stack1.push(0);
stack1.push(-3);
stack1.push(12);
System.out.println(stack1.getMin());
System.out.println(stack1.pop());
stack1.push(-1);
System.out.println(stack1.top());
System.out.println(stack1.pop());
System.out.println(stack1.pop());
System.out.println(stack1.getMin());
}
}
class Solution{
Deque<Integer> stack;
Deque<Integer> minStack;
public Solution(){
stack = new LinkedList<>();
minStack = new LinkedList<>();
minStack.push(Integer.MAX_VALUE);
}
public void push(int val){
stack.push(val);
if(val < minStack.peek()){
minStack.push(val);
}
}
public int pop(){
if(stack.isEmpty()){
throw new RuntimeException("Stack is empty.");
}
int val = stack.peek();
if(val == minStack.peek()){
minStack.pop();
}
return stack.pop();
}
public int top(){
return stack.peek();
}
public int getMin(){
if(minStack.isEmpty()){
throw new RuntimeException("Stack is empty.");
}
return minStack.peek();
}
}
// result
-3
12
-1
-1
-3
-2
问题与思考
- 压入和弹出的规则是对应的
- 在写 top、pop 和 getMin 函数的时候不知道用 peek 还是 pop,这里记住只有 pop 的时候才用 pop,因为是把值删除,其他操作都是获取值,用 peek
- 在 push 的时候,每次将元素压入最小栈之前都需要进行比较,所以最开始栈中一定要有元素,所以在构造方法中把最大值放进去