【基本数据结构】变形题:最小栈的最优解
本问题对应课程链接:剑指offer刷题第三期
这是我在面试遇到的问题,大家可以想一想,如何实现时间和空间都是 O(1),核心突破口在于数值范围,有一定难度。
问题描述:
实现一个这样的栈,这个栈除了可以进行普通的push、pop操作以外,还可以进行getMin的操作,getMin方法被调用后,会返回当前栈的最小值。栈里面存放的都是 int 整数,并且数值的范围是 [-100000, 100000]。要求所有操作的时间复杂度是 O(1)。
附加:如果空间复杂度也能O(1)的话可加分
要求:时间+空间都是O(1)就当作选做吧,你可以说一说你的想法,让空间/尽可能小勒。
答案:明天给答案吧
要求:
1、请打卡你的解题代码,如果能简单说一下思路则简单说一下思路。
2、给出你代码所用的时间复杂度和空间复杂度
答案已经出来了,大家看这个文章解析:Shopee面试:最小栈的最优解
共以下 30 个回答
class MinStack { stack;
//对数值有限制,因为存储差值会越界,时间空间复杂度都为O(1)
Stack
Integer min;
}
“`java stack = new Stack ();
public class 设计一个有gitMina的栈{
private Stack
private int min ;
public void push(int x){
if(stack.isEmpty()){
min = x;
stack.push(0);
}else{
//计算差值
int compare = x-min;
stack.push(compare);
//如果差值小于0,显然x成为最小值,否则最小值
min = compare<0?x:min;
}
}
public void pop(){
int top = stack.peek();
//如果top小于0,显然最小值也一并会被删除,此时更新最小值
min = top<0?(min-top):min;
stack.pop();
}
public int getMin(){
return min;
}
}
通过储存差值来减少空间
【思路】由于[-100000, 100000]数值范围可以产生的最大差值可以用32位int表示,将各个数值与min的差值存入栈中。
【时间复杂度】各个操作均为O(1)
【空间复杂度】额外产生的复杂度为O(1)
代码:
该代码实现了一个最小栈类。最小栈是一个特殊的栈数据结构,除了支持常规的压入(push)、弹出(pop)操作外,还支持获取栈中的最小值(getMin)操作。
在该类中,使用一个列表(stack)来存储栈中的元素,并使用一个变量(min_value)来记录当前的最小值。在初始化时,将最小值设置为正无穷大。
push方法用于将元素压入栈中。如果新元素小于等于当前的最小值,需要将旧的最小值压入栈中,并更新最小值为新的元素。然后将新元素压入栈中。
pop方法用于弹出栈顶的元素。首先弹出栈顶的元素,并将其存储在变量e中。如果弹出的元素等于当前的最小值,说明最小值已经被弹出,需要重新寻找栈中的最小值。将栈顶的元素再次弹出,并更新最小值为该元素。最后返回变量e。
getMin方法用于获取栈中的最小值,直接返回变量min_value即可。
该实现的时间复杂度为O(1),空间复杂度为O(n),其中n为栈中的元素个数。
时间复杂度O(1) 空间复杂度O(1)
转成long类型才不会超过边界
时间复杂度和空间复杂度O(1), 增加了top返回栈顶函数
复刻帅地的代码
时间复杂度O(1) 空间复杂度O(1)
没有其它想法,看的答案,用差值
插值法,栈中存放元素与最小值的差值,每次top操作就利用最小值和栈顶值计算原值;push操作,如果push的值与最小值差大于等于零不更新最小值,如果小于零就更新最新的最小值;pop操作,如果栈顶元素小于零,说明弹出元素是比当前最小值小的,需要更新最小值,几圈方法位:最新最小值 = 现在最小值 – 栈顶值
时间复杂度O(1)
空间复杂度O(1)
考虑 [-100000, 100000]无溢出的话如何利用一个stack实现
C++实现
啊。借鉴,将最小和本身都放在同一个栈里面。
”’java 实现 stack;
class MinStack {
Stack
int min =Integer.MAX_VALUE;
/** initialize your data structure here. */
public MinStack() {
stack=new Stack<>();
}
}
mark一下,mpwexin用户同学、jhfuture同学的代码,看了下实现应该没问题,感谢提供思路
国际站看到的一个解答
这个好难
不用辅助栈的做法。
想不到空间复杂度为O(1)的做法
这道题其实难点在于“怎么保存上一个最小值”,如果只是用一个mini数值进行保存的话,那当min值弹出后就无法知道下一个最小值是什么。然后我们这里可以这样子,更新最小值的时候,将上一个最小值压入栈中,同时出栈时,如果出栈的是最小值,则下一个即为上一个最小值,也将它出栈即可。
时间复杂度为n,空间复杂度为1.
方法一:使用一个栈,栈中每次存放当前值和加入值前的最小值;在pop时,直接得到去掉该值后的最小值