【体验面试】shopee面试:变形的最小栈
本问题对应课程链接:剑指offer刷题第二期
这是我在面试遇到的问题,大家可以想一想,如何实现时间和空间都是 O(1),核心突破口在于数值范围,有一定难度。
问题描述:
实现一个这样的栈,这个栈除了可以进行普通的push、pop操作以外,还可以进行getMin的操作,getMin方法被调用后,会返回当前栈的最小值。栈里面存放的都是 int 整数,并且数值的范围是 [-100000, 100000]。要求所有操作的时间复杂度是 O(1)。
附加:如果空间复杂度也能O(1)的话可加分
要求:时间+空间都是O(1)就当作选做吧,你可以说一说你的想法,让空间/尽可能小勒。
答案:明天给答案吧
答案已经出来了,大家看这个文章解析:Shopee面试:最小栈的最优解
共以下 34 个回答
用这种方法重新提交了一下最小栈问题,有一个测试用例存在溢出问题,需要用long存储
照着打,还是挺难理解的
只使用一个栈,栈中存放的是存放栈顶与最小值的差值
只使用一个stack栈,stack里面不存放原始数值,而是差值。差值=arr[i]-min
感觉思路来自差分数组,用一个基准和差分数组可以恢复原数组
当然本题min并不单纯是一个基准,不过也是可以恢复出原始栈的
之前实现最小栈,用来额外的一个栈min来存放最小值,其实栈min中可能有一些重复的最小值,可以在入栈和出栈出判断是否需要更新最小值来更新最小栈,以此减少一下空间开销。我面试时估计也只能想到这种优化,对于将int型的4个字节拆分为2个字节、2个字节使用,只能用于小范围的数值。最优解是利用数值差,栈中差值,栈顶元素和最小值的差值。当这样只能得到栈中的最小值,栈顶的元素无法获取,也符合题目要求。
没有思路,参考帅老师的解析。
对min从上至下标记,min0, min1···。以pop最后一个为例,当 top < 0 时,即要pop的元素是最小值,那么 min0=x,x-min1=top,所以更新后的最小值 min1 = min0-top,否则min不变。
“`cpp sk_min;
class MinStack {
public:
/** initialize your data structure here. */
stack
int min;
MinStack() {
};
cpp
维护一个实际元素与最小值的差值的栈
时间复杂度空间复杂度都为O(1)
两个栈解决,用辅助栈存放最小值
1、data.top中存放当前x与当前minData的差值
2、弹出时,如果data.top为正,则minData不用改变;如果data.top为负,那么它弹出后,minData需要修正为minData-data。
自己简单写了一个,让用一个栈实现,但是还是有点冗杂,可以再修改
时间复杂度空间复杂度都为O(1)
o(1)的做法就是只维护一个最小值,而不是之前的一个栈。
维护一个值得时候需要在插入的时候得到当前值与最小值的差,问题就来了。
差值是否会导致越界,还是要结合题目来看
致命缺点:由于存储差值,无法解决溢出的可能问题
用带min属性的链表模拟栈
学习新思想,刷好每道题
想用一个值去固定最小值,但没有想出来,看的下面道友的思路想法,使用栈去保存每次的最小值
时间复杂度O(1),空间复杂度O(1)
剑指 Offer 30. 包含min函数的栈 的改进题目
题目要求
规定数据范围为[-100000,100000];
使得空间复杂度和时间复杂度都是O(1);
解法思路
核心思想:使栈中的数据不仅能够保有原来数据是什么的信息,同时保有最小值是如何变化的信息。
push
维护一个用于存储差值的栈(差=实际元素-当前的min值),栈空时,将min设置为当前元素并将栈底设置为0;栈非空时,计算差值diff,如果diff<0,则当前入栈元素小于当前的min,入栈diff并更新元素,如果diff>=0,说明无需更新min,直接将diff入栈即可。
pop
如果差值栈 栈顶元素<0,说明出栈当前栈顶元素后,min值会变大,【因为当前栈顶元素diff<0,所以之前push这个元素的时候,min设置为等于实际值】,而出栈栈顶元素后,min值会被更新为 min-栈顶的diff值。
如果栈顶元素diff>=0,说明此次出栈并不会影响min的值,【因为diff>=0,之前的压栈方式为:计算出diff直接入栈】,所以反向计算 实际值 = diff + min。
min
直接返回min。
top
与pop操作比较类似。
如果差值栈栈顶元素diff<0,说明当前元素实际值为当前的min值。
如果diff>=0,说明当前元素实际值=diff+min。
时间复杂度 O(1)
所有相关函数都不涉及遍历操作。
空间复杂度 O(1)
使用了常量的额外空间
代码
解题思路:空间O(n)复杂度的解法使用的是辅助栈保存最小值,本题目中,栈用于保存x和min之间的差值,当差值小于0时,更新最小值min为当前x,实现O(1)的空间复杂度,各操作时间复杂度也为O(1);
想了很久,只有一个大概的思路,因为想要常数级的空间复杂度,那么最小值的存储只能利用现有的栈,而帅地给了提示注意数值范围,我觉得可以将int的前2个字节用于记录最小值,后面2个字节来记录本来的值,这样就可以完美实现空间复杂度为O(1)了
哈哈,两个2字节记录不了10万的数值哦,不过也是个不错的思路,我也是给了面试官类似的思路。
hh忘记这茬了0.0,实在想不出来更好的了,等一下明天的答案@_@
第五天第三题
时间复杂度:O(1),空间复杂度:O(1)
要给出空间复杂度和时间复杂度哦。
空间复杂度为O(n),时间复杂度为O(1).
学习一波帅地方法, 在纸上模拟一下栈的过程就很清晰了。
虽然没仔细看你的代码,不过正确的方法也是用数值差的方式做哦