栈的最小值

请设计一个栈,除了常规栈支持的pop与push函数以外,还支持min函数,该函数返回栈元素中的最小值。执行push,pop和min操作的时间复杂度必须为O(1)

示例:
MinStack minStack=new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); 返回-3
minStack.pop();
minStack.top(); 返回0;
minStack.getMin(); 返回-2

1‘、使用辅助类解决
定义一个链表如下:

class ListNode{
	public inr val;
	public int min;
	public ListNode next;

	public ListNode(int val,int min,ListNode next){
			this.val=val;
			this.min=min;
			this.next=next;
	}
}

对链表的操作永远都是链表的头,假如在栈中加入3-2-5-4
在这里插入图片描述
整体代码:

class MinStack{
	//链表头,相当与栈顶
	private ListNode head;
	
	//判断栈是否为空
	private boolean empty(){
		return head==null;
	}
	
	//压栈,需要判断栈是否为空
	public void push(int x){
		if(empty()){
			head=new ListNode(x,x,null);
		}else{
			head=new ListNode(x,Math.min(x,head.min),head);
		}
	}

	//出栈,相当于把链表头删除
	public void pop(){
		if(empty()){
			throw new IllegalStateException("栈为空....");
		}
		return head.val;
	}

	//链表中头结点保存的是整个链表最小的值,所以返回head.min也就是返回栈中最小的值
	public int min(){
		if(empty()){
			throw new IllegalStateException("栈为空.....");
		}
	return head.min;
	}
}

class ListNode{
	public int val;
	public int min;
	public ListNode next;
	public ListNode(int val,int min,ListNode next){
		this.val=val;
		this.min=min;
		this.next=next;
	}
}

上面解决方式是使用一个辅助的类,实际上如果使用辅助类,我们也可以使用官方提供的栈

class StackNode{
	public int val;
	public int min;
	public StackNode(int val,int min){
		this.val=val;
		this.min=min;
	}
}

class MinStack{
	private Stack<StackNode> stack=new Stack<>();

	//判空
	public boolean empty(){
		return stack.isEmpty();
	}
	
	//压栈
	public void push(int x){
		if(empty()){
			stack.push(new StackNode(x,x));
		}else{
			stack.push(new StackNode(x,getMin()));
		}
	}
	
	//出栈
	public void pop(){
		if(empty()){
			throw new IllegalStateException("栈为空....");
		}
	}


	//显示栈顶值
	public int top(){
		if(empty()){
			throw new IllegalStateException("栈为空....");
		}
		return stack.peek().val;
	}

	//最小值
	public int getMin(){
    	if(empty()){
			throw new IllegalStateException("栈为空.....");
		}
		return stack.peek().min;
	}
}

维护两个栈,一个是主栈,一个是最小栈
1、每次push操作将元素插入主栈栈顶时,同时判断是否小于等于最小栈点的栈顶元素,如果是则插入最小栈
2、每次pop操作,主栈栈顶元素如果等于最小栈栈顶元素,则同步出栈
3、min操作则返回最小栈的top值
因为主栈的第一个元素一定插入最小栈,所以不用担心最小栈为空的情况

class MinStack{
	private Stack<Integer> stack;
	private Stack<Integer> minRecord;
	
	public MinStack(){
		this.stack=new Stack();
		this.minRecord=new Stack();
	}

	public void push(int x){
		stack.push(x);
		if(minRecord.isEmpty() || minRecord.peek()>=x){
			minRecord.push(x);
		}
	}

	public void pop(){
		int res=stack.pop();
		if(minRecord.peek()>=res){
			minRecord.pop();
		}
	}

	public int top(){
		return stack.peek();
	}

	public int getMin(){
		return minRecord.peek();
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值