前言:
在力扣上关于最小栈的问题,看到一个非常聪明简单的栈设计,和大家分享一下。
原题目描述:
解题思路:
容器设计:
由于该栈要求我们能检索出栈中的最小元素,如果使用最原始的栈设计,我们在取最小值时,需要依次从栈顶开始往栈底遍历去找,可以解出题目,但是显然不够聪明,所以我们设计这个栈时,选用单链表来存储元素,并且在每个节点中添加一个属性来保存最小值:
//自定义Node,用min存放最小值
private class Node{
int val; //保存当前元素的值
int min; //保存最小值
Node next; //保存指向的下一个节点
//自定义Node的构造方法
private Node(int val,int min){
this.val = val;
this.min = min;
this.next = null;
}
private Node(int val,int min,Node next){
this.val = val;
this.min = min;
this.next = next;
}
}
PUSH方法:
根据上述设计,思路就是在向栈中push元素时,我们都将目前栈中的最小值与当前要push的元素值进行比较,如果当前元素值更小,则使当前元素变成头结点的同时将最小值保存到头结点的min属性:
public void push(int val) {
if(head == null){
//第一次压入元素时,val值即为最小值
head = new Node(val,val);
}else{
//将最小值赋值给head节点的min
head = new Node(val,Math.min(val, head.min),head);
}
}
完整代码:
public class LeetCode_155 {
private Node head;
public void push(int val) {
if(head == null){
head = new Node(val,val);
}else{
head = new Node(val,Math.min(val, head.min),head);
}
}
public void pop() {
head = head.next;
}
public int top() {
return head.val;
}
public int getMin() {
return head.min;
}
//自定义Node,用min存放最小值
private class Node{
int val;
int min;
Node next;
//自定义Node的构造方法
private Node(int val,int min){
this.val = val;
this.min = min;
this.next = null;
}
private Node(int val,int min,Node next){
this.val = val;
this.min = min;
this.next = next;
}
}
}
优化点:
由于我们每次压入元素时都更新了head的最小值,所以在取最小值时,我们只需要返回head节点的min即可,相比最简单的栈节省了遍历的时间,效率很高。