题目描述
定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。
注意:保证测试中不会当栈为空的时候,对栈调用pop()或者min()或者top()方法。
首先读懂题目,需要保留所有栈的特性(先进后出),并且该栈中有能够提供找到最小元素的min函数。普通的栈是无法实现的。说白了就是让你设计一个栈,其中有一个函数时可以返回最小值的。显然这个栈不是让你写从零写起,你可以依托于包中的栈的普通方法,而把焦点在如何实现min函数
不能用一个变量记录最小值,因为当最小值弹栈后,该变量就得变成新的最小值,这个不容易实现。所以需要定义一个辅助的数据结构,可以记录多个变量,可以随着原来的栈的弹出压入而更新对应的最小值。
第一想法是使用最小堆,但是最小堆还需要实现。既然本身可以依托于包中的栈,那么比较讨巧的做法就是用一个辅助栈。
因此需要设计辅助栈的压入规则和弹出规则:
写法1:
用一个栈data保存数据,用另外一个栈min保存依次入栈最小的数
比如,data中依次入栈,5, 4, 3, 8, 10, 11, 12, 1
则min依次入栈,5, 4, 3,3, 3, 3, 3, 1
每次入栈的时候,如果入栈的元素比min中的栈顶元素小或等于则两边都入栈,否则辅助栈压入一个当前的最小值。这样可以保证两个栈的入栈的数量是一致的。
import java.util.Stack;
public class Solution {
Stack<Integer> stack_data=new Stack<Integer>();//原来的栈
Stack<Integer> stack_min=new Stack<Integer>();//辅助栈
public void push(int node) {
stack_data.push(node);//原来的栈肯定要入的
if(stack_min.empty() || stack_min.peek()>node) {//为空就使用不了peek
stack_min.push(node);//当前数更小则当前数入栈
}else {
stack_min.push(stack_min.peek());//否则压入辅助栈的最小值
}
}
public void pop() {
if(!stack_data.empty()) {//同时弹
stack_data.pop();
stack_min.pop();
}
}
public int top() {//返回原栈的栈顶元素
return stack_data.peek();
}
public int min() {//返回辅助栈的栈顶元素
return stack_min.peek();
}
}写法2
用一个栈data保存数据,用另外一个栈min保存依次入栈最小的数
比如,data中依次入栈,5, 4, 3, 8, 10, 11, 12, 1
则min依次入栈,5, 4, 3,null, null, null, null, 1
null就是不入栈。也就是只有出现最小值时,辅助栈才会入栈。而弹出时,原栈和辅助栈的栈顶相同时,辅助栈才会弹栈。
import java.util.Stack;
public class Solution {
Stack<Integer> stack_data=new Stack<Integer>();
Stack<Integer> stack_min=new Stack<Integer>();
public void push(int node) {
stack_data.push(node);//反正原栈肯定要入的
if(stack_min.empty() || stack_min.peek()>node) {
//出现较小值才入栈,否则不操作
stack_min.push(node);
}
}
public void pop() {
if(!stack_data.empty()) {//首先判断不为空
if(stack_data.peek() != stack_min.peek())
//不相等,说明弹出的不是当前最小值,原栈弹出就可以
stack_data.pop();
else{//是最小值,两个栈一起弹
stack_data.pop();
stack_min.pop();
}
}
}
public int top() {
return stack_data.peek();
}
public int min() {
return stack_min.peek();
}
}总结:其实很多算法题考点不同,本题的考点在于如何实现Min函数,因此不需要考虑太多栈的设计考察一个栈如何设计,并不是说栈的设计不重要,只是本题的侧重点不在与栈的设计,有些大佬功底比较厚,考虑的也比较多,这也正常。非大佬就把握好考点就好啦。
附上左神的一张图,构造函数都搞出来了,把一些思想用进来就很强势。还有些大佬在回答中进行扩容的,是真的强。
说明:这个和写法2的原理相同



京公网安备 11010502036488号