最小(大)栈
标明:以下代码为最小栈讲解,求最大栈只需将入栈判断条件做以修改即可。
题目描述:
设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈。
push(x
) -- 将元素 x 推入栈中。
pop() -- 删除栈顶的元素。
top() -- 获取栈顶元素。
getMin() -- 检索栈中的最小元素。
测试示例:
MinStack minStack
= new MinStack();
minStack
.push(-2);
minStack
.push(0);
minStack
.push(-3);
minStack
.getMin(); --> 返回
-3.
minStack
.pop();
minStack
.top(); --> 返回
0.
minStack
.getMin(); --> 返回
-2.
题目解析:
我们通过解析题目可以知道,该题实际上是要求我们自定义一个栈,实现简单的入栈、出栈、弹出最顶层元素三个基础功能。最核心的是要实现返回最小栈元素(要求时间复杂度在常数范围内,即O(常数))。
两种解题思路:
针对于题目对时间复杂度的要求,我们可有以下两种解题思路:
1.双栈思路。因题目只对时间复杂度有要求,而对空间复杂度无要求。因此我们可以创建两个栈,一个栈用于存储实际数据,另一个栈用于存储最小元素,getMin()方法只需直接返回存储最小元素栈的最顶层元素即可。
双栈思路时间复杂度为O(1),空间复杂度为O(n)。
2.单栈思路。假设该题对时间复杂度和空间复杂度都要求为O(1)时,我们就可使用该方法实现。单栈顾名思义就是只创建一个栈,我们进行入栈操作时可push()两次,第一次为实际数据,第二次为最小元素(即每个实际数据后面均跟着最小元素),getMin()方法只需直接返回栈顶元素即可。
双栈思路和单栈思路图解:
双栈思路:
单栈思路:
双栈思路实现代码:
import java
.util
.Stack
;
class MinStack {
private Stack
<Integer> dataStack
;
private Stack
<Integer> minDataStack
;
public MinStack() {
dataStack
=new Stack<>();
minDataStack
=new Stack<>();
}
public void push(int x
) {
if(minDataStack
.isEmpty()||x
<=minDataStack
.peek()){
minDataStack
.push(x
);
}
dataStack
.push(x
);
}
public void pop() {
if(dataStack
.peek().equals(minDataStack
.peek())){
minDataStack
.pop();
}
dataStack
.pop();
}
public int top() {
return dataStack
.peek();
}
public int getMin() {
return minDataStack
.peek();
}
}
public class Main{
public static void main(String
[] args
) {
MinStack stackTest
=new MinStack();
stackTest
.push(1);
stackTest
.push(2);
stackTest
.push(3);
System
.out
.println(stackTest
.top());
stackTest
.pop();
System
.out
.println(stackTest
.getMin());
}
}
单栈思路:
import java
.util
.Stack
;
class MinStack{
private Stack
<Integer> stack
;
public MinStack() {
stack
=new Stack<>();
}
public void push(int x
){
if(stack
.isEmpty()){
stack
.push(x
);
stack
.push(x
);
}else {
int temp
=stack
.peek();
stack
.push(x
);
if(x
<=temp
){
stack
.push(x
);
}else {
stack
.push(temp
);
}
}
}
public void pop(){
if(stack
.isEmpty()){
System
.out
.println("当前栈为空");
return;
}
stack
.pop();
stack
.pop();
}
public int top(){
if(stack
.isEmpty()){
System
.out
.println("当前栈为空");
}
int result
=stack
.pop();
int data
=stack
.peek();
stack
.push(result
);
return data
;
}
public int getMin(){
return stack
.peek();
}
}
public class Main{
public static void main(String
[] args
) {
MinStack stackTest
=new MinStack();
stackTest
.push(1);
stackTest
.push(2);
stackTest
.push(3);
System
.out
.println(stackTest
.top());
stackTest
.pop();
System
.out
.println(stackTest
.getMin());
}
}