标签:public 保存 支持 现在 需要 remove 解决 else 常数时间
2020年3月21日
Design a stack that supports push, pop, top, and retrieving the minimum element in constant time.
Example:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); --> Returns -3.
minStack.pop();
minStack.top(); --> Returns 0.
minStack.getMin(); --> Returns -2.
设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈。
示例:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); --> 返回 -3.
minStack.pop();
minStack.top(); --> 返回 0.
minStack.getMin(); --> 返回 -2.
最直接的方法是用两个栈,一个保存正常的入栈出栈的值,另一个栈去存最小值,也就是用当前栈顶保存当前所有元素的最小值,流程如下:
class MinStack{
private Stack<Integer> stack;
private Stack<Integer> minStack;
public MinStack(){
stack=new Stack<>();
minStack=new Stack<>();
}
public void push(int x){
stack.push(x);
if(!minStack.isEmpty()){
int top=minStack.peek();
//小于等于的时候才入栈
if(x<=top){
minStack.push(x);
}
}else{
minStack.push(x);
}
}
public void pop(){
int pop=stack.pop();
int top=minStack.peek();
//等于的时候再出栈
if(pop==top){
minStack.pop();
}
}
public int top(){
return stack.peek();
}
public int getMin(){
return minStack.peek();
}
public int getMin(){
return minStack.peek();
}
}
方法1中使用了两个栈实现,那么现在尝试用一个栈实现,只用一个变量去保存最小值,如果新压入的值更小,那么在压入新元素前将原来的min压入栈中,并更新最小值
class minStack{
int min = Integer.MIN_VALUE;
Stack<Integer> stack = new Stack<Integer>();
public void push(int x){
if(x<=min){
stack.push(min);
min=x;
}
stack.push(x);
}
public void pop(){
if(stack.pop()==min){
min = stack.pop();
}
}
public int top(){
return stack.peek();
}
public int getMin(){
return min;
}
}
从方法2中可以看出,关键要解决的问题是当有新的更小值的时候,之前的最小值怎么办?
方法3用另一种思路,通过min存储当前最小值,栈中存储入栈的值与最小值的差值
public class MinStack{
long min;
Stack<long> stack;
public MinStack(){
stack=new Stack<>();
}
public void push(int x){
if(stack.isEmpty()){
min=x;
stack.push(x-min);
}else{
stack.push(x-min);
if(x<min){
min=x;
}
}
}
public void pop(){
if(stack.isEmpty()) return;
long pop = stack.pop();
if(pop<0){
min=min-pop;
}
}
public int top(){
long top=stack.peek();
if(top<0){
return (int)(min);
}else{
return (int)(top+min);
}
}
public int getMin(){
return (int) min;
}
}
上述解法的一个缺点是保存的是差值,所以可能造成溢出,所以用了范围更大的long类型,这个解法在最小值更新时不需要把之前的最小值存起来,会节省一些空间
不用java提供的stack,在Node结点中增加min字段
class MinStack{
class Node{
int value;
int min;
Node next;
Node(int x,int min){
this.value=x;
this.min=min;
next=null;
}
}
Node head;
public void push(int x){
if(null==head){
head=new Node(x,x);
}else{
Node n = new Node(x,Math.min(x,head.min))
n.next=head;
head=n;
}
}
public void pop(){
if(head!=null)
head=head.next;
}
public int top(){
if(head!=null)
return head.value;
return -1;
}
public int getMin(){
if(head!=null)
return head.min;
return -1;
}
}
标签:public 保存 支持 现在 需要 remove 解决 else 常数时间
原文地址:https://www.cnblogs.com/ningdeblog/p/12542013.html