牛客试题:包含min函数的栈
描述
定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的 min 函数,输入操作时保证 pop、top 和 min 函数操作时,栈中一定有元素。
此栈包含的方法有:
push(value):将value压入栈中
pop():弹出栈顶元素
top():获取栈顶元素
min():获取栈中最小元素
数据范围:操作数量满足0≤n≤300 ,输入的元素满足 ∣val∣≤10000
进阶:栈的各个操作的时间复杂度是O(1) ,空间复杂度是 O(n)
示例:
输入: [“PSH-1”,“PSH2”,“MIN”,“TOP”,“POP”,“PSH1”,“TOP”,“MIN”]
输出: -1,2,1,-1
解析:
"PSH-1"表示将-1压入栈中,栈中元素为-1
"PSH2"表示将2压入栈中,栈中元素为2,-1
“MIN”表示获取此时栈中最小元素==>返回-1
"TOP"表示获取栈顶元素==>返回2
"POP"表示弹出栈顶元素,弹出2,栈中元素为-1
"PSH1"表示将1压入栈中,栈中元素为1,-1
"TOP"表示获取栈顶元素==>返回1
“MIN”表示获取此时栈中最小元素==>返回-1
示例1
输入:
[“PSH-1”,“PSH2”,“MIN”,“TOP”,“POP”,“PSH1”,“TOP”,“MIN”]
复制
返回值:
-1,2,1,-1
答案使用了Stack类来辅助实现了O(1)的复杂度Top,Min等函数。其实也可以只使用数组来实现。
思路:由于输入范围小于300,那么可以使用数组来实现栈。将0位置作为栈底即可,使用变量num指向当前数组元素的下标即可,压栈操作就是在num+1个位置放置元素,出栈就是将num减一。
Top的实现也很简单,返回当前的num位置的值即可。主要是Min的实现,如果去遍历数组的话,复杂度就是O(n),不是O(1)。为了实现O(1),可以再使用一个栈来保存min的值。
可以这样理解,有一个栈m,m里面保存的是历史的最小值,比如第一个元素进来,第一个元素就是最小的,这个元素入栈,如果第二个元素进来并且比第一个元素小,那么将第二个元素入栈,那么栈顶总是最小的元素。如果第二个需要出栈,那么将这个元素和m的栈顶元素进行比较,如果相等,那么表明当前弹出的元素是最小的元素,需要更新栈顶(即将栈顶元素弹出)。
总之,栈m的栈顶始终是最小的元素。
代码如下:
import java.util.*;
public class Solution {
int[] stack = new int[300];//栈的数组实现
int num = -1;//指向栈顶位置
int[] min = new int[300];//维护最小值,栈顶始终是目前最小的元素
int indexMin = -1;//指向min的顶部
public void push(int node) {
//入栈
num++;
stack[num] = node;
//维护最小值
//储存最小值的栈为空的情况
//将第一个元素进行储存
if(indexMin == -1){
min[0] = node;
indexMin++;
}else{
//其余情况,更新最小值
//主要是相等也要保存下来,因为
//当删除元素等于最小值时,是会删除最小值的
//如果相等的不保留,那么最小值就会变化
if(node<=min[indexMin]){
indexMin++;
min[indexMin] = node;
}
}
}
public void pop() {
//出栈,如果出栈的元素是最小值,那么既要更新栈又要更新最小值
if(stack[num]==min[indexMin]){
indexMin--;
}
num--;
}
public int top() {
return stack[num];
}
public int min() {
return min[indexMin];
}
}