一、问题描述
二、解题思路
2.1 常规思路(辅助栈)
基本思路:设计两个栈来实现minstack,其中常规栈stack存储元素数据,最小栈minstack存放最小元素,并将最小的元素放置在栈顶。
var MinStack=function(){
this.stack=[];
this.minstack=[];
}
MinStack.prototype.push=function(val){
//常规栈正常存放全部数据,最小栈只追加存放当前元素中的最小值
this.stack.push(val);
//最小栈新增元素的条件只有两个,1、最小栈没有元素;2、最小栈栈顶元素小于等于当前要存入的元素(等于号很重要,这里是为了放置重复元素存在导致pop删除了最小值而最小栈没有记录)
if(!this.minstack.length||val<=this.minstack[this.minstack.length-1])
this.minstack.push(val);
}
MinStack.prototype.pop=function(){
let val=this.stack.pop();
if(val==this.minstack[this.minstack.length-1])
this.minstack.pop();
}
MinStack.prototype.top=function(){
return this.stack[this.stack.length-1];
}
MinStack.prototype.getMin=function(){
return this.minstack[this.minstack.length-1];
}
2.2 基栈+差值存储
基本思路:栈内不直接存储要存入栈的值,而是存储要存入栈的值与当前最小值的差,并在出入栈时更新当前最小值。
- 入栈操作:栈为空时直接入栈,并将最小值设置为当前值;若栈不为空,则将当前值与最小值做差,差为负数说明当前入栈值为最小值,则更新最小值,否则最小值不变,将差值入栈。(更新最小值时,之前元素与当前最小值的差值如何计算?这里不需要改变,因为每次取值的时候进行计算都是和当前的最小值进行计算。之前元素的最小值是当前最小值入栈之前的最小值。)
- 出栈操作:需要进行逆运算恢复原值,并正确更新最小值。入栈的操作决定了,当前栈内存储的值都是入栈时的“原始值”与入栈前最小值的差。那么意味着,当栈顶元素为负值时,说明该元素入栈时的原始值比之前的最小值要小,最小值则被更新为改原始值了,所以此时直接出栈最小值即为原始值。那么如何更新最小值呢?由于栈顶的值是原始值与入栈前最小值的差,那么现在有了原始值和差值,便可以计算出入栈前的最小值=原始值-差值。当栈顶元素为正值时,说明该元素入栈时原始值比入栈前的最小值大,最小值无需更新。那么出栈原始值=最小值+差值,保持最小值即可。
var MinStack=function(){
this.minval=-1;
this.stack=[];
}
MinStack.prototype.push=function(val){
if(!this.stack.length){
this.stack.push(0);//与最小值的差值为0
this.minVal=val;
}else{
let dif=val-this.minval;
this.stack.push(dif);
if(dif<0) this.minval=val;
}
}
MinStack.prototype.pop=function(){
let dif=this.stack.pop();
if(dif<0) this.minval=this.minval-dif;
}
MinStack.prototype.top=function(){
let dif=this.stack[this.stack.length-1];
//dif<0,说明栈顶元素就是最小值那个元素
if(dif<0) return this.minval;
else return this.minval+dif;
}
MinStack.prototype.getMin=function(){
return this.minval;
}
2.3 只用基栈
基本思路:在栈中记录最小值。
- 入栈操作:若当前元素值小于最小值,则更新最小值为当前元素值,并将前一个最小值入栈,否则直接入栈。
- 出栈操作,若当前出栈元素与当前最小值相等,则更改最小值为当前出栈元素的上一个元素。
示例:
var MinStack = function() {
this.stack = [];
this.min = Number.MAX_SAFE_INTEGER;
};
MinStack.prototype.push = function(val) {
//当前值比最小值更小
if(val<=this.min){
//将上一个最小值保存入栈
this.stack.push(this.min);
//更新当前最小值
this.min=val;
}
this.stack.push(val);
};
MinStack.prototype.pop = function(){
//如果弹出值等于当前最小值,那么再弹出一次的值就是上一个最小值也就是当前元素出栈后应该更新的最小值
if(this.stack.pop()==this.min){
this.min=this.stack.pop();
}
};
MinStack.prototype.top = function() {
return this.stack[this.stack.length-1];
};
MinStack.prototype.getMin = function() {
return this.min;
};