155. 最小栈

94 阅读2分钟

力扣(LeetCode)链接:leetcode-cn.com/problems/mi…

设计一个支持 push ,pop ,top 操作,并能在常数O(1)时间内检索到最小元素的栈。

  • push(x) —— 将元素 x 推入栈中。
  • pop() —— 删除栈顶的元素。
  • top() —— 获取栈顶元素。
  • getMin() —— 检索栈中的最小元素。   示例:
 输入:
["MinStack","push","push","push","getMin","pop","top","getMin"]
[[],[-2],[0],[-3],[],[],[],[]]

输出:
[null,null,null,null,-3,null,0,-2]

解释:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin();   --> 返回 -3.
minStack.pop();
minStack.top();      --> 返回 0.
minStack.getMin();   --> 返回 -2.

提示:

poptopgetMin 操作总是在 非空栈 上调用。

思路1:

创建一个数据栈A和一个辅助栈B, A用于存放push进来的数据,B用于存放最小值数据。 每当有元素入栈A时,都要获取到当前栈的最小值放入栈B中。每当栈A有元素出栈时,栈B也要做出栈操作。这样,栈B的栈顶存放的永远是当前栈中最小元素。

题解1:

class MinStack {

    /** initialize your data structure here. */
    Stack<Integer> dataStack; // 数据栈 
	Stack<Integer> minStack;  // 最小栈
	
    public MinStack() {
    	dataStack = new Stack<Integer>();
    	minStack = new Stack<Integer>();
    }
    
    public void push(int x) {
    	dataStack.push(x);
    	
    	if (minStack.isEmpty()) {
    		minStack.push(x);
    	} else {
    		int min = minStack.peek();
    		if (x < min) {
    			min = x;
    		}
    		minStack.push(min);
    	}
    }
    
    public void pop() {
    	dataStack.pop();
    	minStack.pop();
    }
    
    public int top() {
    	return dataStack.peek();
    }
    
    public int getMin() {
    	return minStack.peek();
    }
}

/**
 * Your MinStack object will be instantiated and called as such:
 * MinStack obj = new MinStack();
 * obj.push(x);
 * obj.pop();
 * int param_3 = obj.top();
 * int param_4 = obj.getMin();
 */

思路2:

定义一个节点类,用于存放元素值和最小值。创建一个栈A,用于存放节点的数据,每当有元素进栈时,将新增元素和当前的最小值封装到节点中,然后节点入栈。这样,获取栈中最小值就存储在栈顶的节点的最小值中。

题解2:

class MinStack {

    /** initialize your data structure here. */
    private static class Node {
		int val;
		int min;
		public Node(int val, int min) {
			this.val = val;  // 用于存储元素
			this.min = min;  // 用于存储最小值
		}
	}
	
	private Stack<Node> stack;
	public MinStack() {
		stack = new Stack<Node>();
    }
	
	public void push(int x) {
		if (stack.isEmpty()) {
			stack.push(new Node(x, x));
		} else {
			stack.push(new Node(x, Math.min(x, stack.peek().min)));
		}
    }
    
    public void pop() {
    	stack.pop();
    }
    
    public int top() {
    	return stack.peek().val;
    }
    
    public int getMin() {
    	return stack.peek().min;
    }
}

思路3:

使用链表实现,入栈元素封装成节点插入到头部。

题解3:

class MinStack {

    /** initialize your data structure here. */
    private static class Node {
		int val;
		int min;
		Node next;
		public Node(int val, int min, Node nexNode) {
			this.val = val;
			this.min = min;
			this.next = nexNode;
		}
	}
	
	private Node head;
	public MinStack() {
		head = null;
    }
	
	public void push(int x) {
		if (head == null) {
			head = new Node(x, x, null);
		} else {
			head = new Node(x,Math.min(x, head.min) , head);  // 在头部插入
		}
    }
    
    public void pop() {
    	head = head.next;
    }
    
    public int top() {
    	return head.val;
    }
    
    public int getMin() {
    	return head.min;
    }
}