描述
定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数,并且调用 min函数、push函数 及 pop函数 的时间复杂度都是 O(1)
push(value):将value压入栈中
pop():弹出栈顶元素
top():获取栈顶元素
min():获取栈中最小元素
示例:
输入: ["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
"PSH-1"表示将1压入栈中,栈中元素为1,-1
"TOP"表示获取栈顶元素==>返回1
“MIN”表示获取此时栈中最小元素==>返回-1
解法一:利用辅助栈
根据栈的性质很容易得知push函数 及 pop函数 的时间复杂度都是 O(1),但min函数时间复杂度明显不为O(1),最容易思考的方法则为创建一个辅助栈,即利用空间换时间,思路如下:
- 创建一个辅助栈,为后续取栈中最小值做准备
- push方法构建:先将元素压入原栈内,若辅助栈为空或者辅助栈栈顶元素>该元素值,则将该元素放入辅助栈,否则辅助栈中压入上次栈顶元素(这样即可保持辅助栈栈顶元素一直为最小值)
- pop时将原栈及辅助栈中栈顶元素均pop即可,这样即可保持原栈及辅助栈元素个数一致
- top时只需要获取原栈中top元素
- min时从辅助栈获取top元素即可
push方法简易图解:
代码如下:
//创建原栈及辅助栈
private Stack<Integer> originalData = new Stack<Integer>();
private Stack<Integer> minData = new Stack<Integer>();
public void push(int node) {
originalData.push(node);
if(minData.isEmpty() || node <= minData.peek()){ //
minData.push(node);
}else{
minData.push(minData.peek());//当压入的结点大时,则每次都压入min栈顶的值。
}
}
public void pop() {
originalData.pop();//出栈时,min栈和data栈均出栈
minData.pop();
}
public int top() {
return originalData.peek();
}
public int min() {
return minData.peek();
}时间复杂度:O(1)
空间复杂度:因为利用了辅助栈,空间复杂度O(n)
解法二:压缩转换法
由方法一很容易得知辅助栈存储的即为最小值,我们可利用该性质构建一个变量min,并将其放入栈中,最后即可得到一个栈及冗余变量min
简单图解如下:
由上面两图思想可得代码如下:
private Stack<Integer> stack = new Stack<Integer>();
private int min = 0;
public void push(int node) {
if(stack.isEmpty()){
min = node; //栈为空时,将min值赋值为node
}
stack.push(node-min); //将node-min的差值即diff放入栈中
if(min>node){
min = node; //保证min值为node元素最小值
}
}
public void pop() {
if(!stack.isEmpty()){
int val = stack.pop();
if(val<0){
min = min-val; //若差值小于0,则说明出栈元素是当前最小值min,则需将min跟新为前一个最小值
}
}
}
public int top() {
int val = stack.peek();
if(val<0){ //若diff小于0,则value为min值,否则,value值为min+val
return min;
}else{
return min+val;
}
}
public int min() {
return min;
}时间复杂度:O(1)
空间复杂度:额外空间复杂度为O(1)

京公网安备 11010502036488号