最小栈
设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
- push(x) —— 将元素 x 推入栈中。
- pop() —— 删除栈顶的元素。
- top() —— 获取栈顶元素。
- getMin() —— 检索栈中的最小元素。
第一种方法是利用辅助栈
用一个栈存储数据,再用一个栈存储最小值
算法关键:
- 在一开始将Integer.MAX_VALUE压入辅助栈栈底
- 每当push一个新元素的时候,与辅助栈栈顶元素比较 将比较小的一个元素压入栈中(当辅助栈栈顶元素为最小值的时候压入一样的即可)
- 当pop一个元素的时候,辅助栈也一起pop
tips:pop、top 和 getMin 操作总是在 非空栈 上调用。
代码实现
package QueueAndStack.Stack;
import java.util.*;
/**
* 最小栈
* 设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
*
* push(x) —— 将元素 x 推入栈中。
* pop() —— 删除栈顶的元素。
* top() —— 获取栈顶元素。
* getMin() —— 检索栈中的最小元素。
*
*/
public class MinStack {
//利用辅助栈实现最小栈
/** initialize your data structure here. */
Deque<Integer> stack;
Deque<Integer> minStack;
public MinStack() {
stack=new LinkedList<>();
minStack=new LinkedList<>();
minStack.push(Integer.MAX_VALUE);
}
public void push(int x) {
stack.push(x);
//对比现在栈顶元素和当前元素大小 把小的入栈
minStack.push(Math.min(minStack.peek(),x));
}
public void pop() {
if (!stack.isEmpty()) {
stack.pop();
minStack.pop();
}
}
public int top() {
//空的时候不调用
return stack.peek();
}
//空的时候不调用
public int getMin() {
return minStack.peek();
}
}
第二种方法是利用差值
时间复杂度O(1),空间复杂度O(n)
定义一个数据栈存放差值diff ,定义一个minValue存放最小值
其中diff=node-minvalue node是新push的数据
算法关键:
push
操作
当栈为空的时候,数据栈压入0,minvalue
压入node
因为第一个就是最小值 且差值为0
当栈不为空的时候:
当diff<=0
此时node
比minvalue
还小或者等于,所以此时把diff压入栈中 且minValue
=node
当diff>0
此时node
比minValue
‘大 所以此时只需要把diff压入栈中pop
操作(需要考虑minvalue
)
取出栈顶获得diff
当diff<=0
因为diff=node-minValue
diff<=0说明node
比较小或者等于最小值 那么node=diff+minvalue
所以之前的minvalue=现在的minvalue(也就是node)-diff
minValue
=minValue
-diff
而当diff>0的时候
说明node节点导入的时候不是最小值,不用修改minValue- pop操作
当diff<=0
直接返回minValue
当diff>0
返回node
=diff
+minValue
代码实现:
package QueueAndStack.Stack;
import java.util.*;
/**
* 最小栈
* 设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
*
* push(x) —— 将元素 x 推入栈中。
* pop() —— 删除栈顶的元素。
* top() —— 获取栈顶元素。
* getMin() —— 检索栈中的最小元素。
*
*/
public class MinStack {
//利用差值 diff 2147483647 和-2147483648
Deque<Integer> stack;
int minValue;
public MinStack() {
stack=new LinkedList<>();
}
public void push(int x) {
//栈为空的时候
if (stack.isEmpty()){
stack.push(0);//差值为0
minValue=x;
}else{
int diff=x-minValue;
if (diff>0){
//说明x不是最小值 直接放进栈中
stack.push(diff);
}else{
//说明x比最小值还小 更新最小值
stack.push(diff);
minValue=x;
}
}
}
public void pop() {
int diff=stack.pop();//获取并删除栈顶元素
if (diff<=0){
//因为diff=x-minvalue diff<=0说明x比较小或者等于最小值 那么x=diff+minvalue
//所以之前的minvalue=现在的minvalue(也就是x)-diff
minValue=minValue-diff;
}
//因为diff=x-minvalue diff>0说明x比较大 那么x=diff+minvalue
//所以minValue值不用变动
}
public int top() {
int diff=stack.peek();
return diff<=0?minValue:diff+minValue;
}
public int getMin() {
return minValue;
}
}