Algorithm 持续时间内的推、弹出、范围
我在一次采访中被问到: 设计一个数据结构,允许所有这些操作以恒定的时间(Algorithm 持续时间内的推、弹出、范围,algorithm,data-structures,Algorithm,Data Structures,我在一次采访中被问到: 设计一个数据结构,允许所有这些操作以恒定的时间(O(1))进行: 推动一个元素 弹出一个元素 元素范围:查找当前元素的最小间隔范围。 例如,[1,22,44,56,99,98,56]的范围是98 我使用带有两个变量的定制堆栈来设计它,max和min,但是在弹出一个min或max元素后,这就不起作用了 我尝试的是: 我使用了一个包含两个额外变量max和min的堆栈: DS { top, //Top of the Stack min, //Min till now
O(1)
)进行:
- 推动一个元素
- 弹出一个元素
- 元素范围:查找当前元素的最小间隔范围。
例如,
的范围是[1,22,44,56,99,98,56]
98
max
和min
,但是在弹出一个min或max元素后,这就不起作用了
我尝试的是:
我使用了一个包含两个额外变量max和min的堆栈:
DS
{
top, //Top of the Stack
min, //Min till now
max //Max till now
}
Push(DS, elem)
Push_Stack(DS.top, elem)
if elem < DS.min
DS.min = elem
if elem > DS.max
DS.max = elem
Range(DS)
return DS.max - DS.min
Pop(DS)
x = Pop_Stack(DS.top)
if (x == DS.min)
DS.min = Find_New_Min(DS.top) //This takes linear time using this approach
if (x == DS.max)
DS.max = Find_New_Max(DS.top)
DS
{
top,//堆栈的顶部
min,//min到现在
max//max到现在为止
}
推送(DS、elem)
推送堆栈(DS.top,elem)
如果elemDS.max
DS.max=elem
射程(DS)
返回DS.max-DS.min
流行音乐(DS)
x=Pop_堆栈(DS.top)
如果(x==DS.min)
DS.min=Find_New_min(DS.top)//使用这种方法需要线性时间
如果(x==DS.max)
DS.max=Find_New_max(DS.top)
实现一个包含范围函数的“堆栈”,并在内部使用三个堆栈
第一个内部堆栈将表示被推送和弹出的“真实”堆栈 只有当新元素大于或等于其顶部的元素时,才会将第二个内部堆栈推送到 只有当新元素小于或等于其顶部的元素时,才会推送到第三个内部堆栈
现在,无论何时需要计算范围,只需查看第二和第三堆栈的顶部,并做一些简单的数学运算 每当需要从“真实”堆栈中弹出一个元素时,检查该元素是否也位于其他两个堆栈的顶部,如果是,也将其从这些堆栈中弹出
因为你必须以相反的顺序从主堆栈中弹出项目,所以你不会错过其他两个堆栈中的任何东西。。。这意味着第二个和第三个内部堆栈的顶部将始终是最大值和最小值。这类似于Bryon Lo的回答,但在他发布我的 保持3个堆栈
- S1你的最后一堆
- S2和S3临时堆栈
push(T value)
{
if (value <= min())
{
s2.push(value);
}
if(value >= max())
{
s3.push(value);
}
s1.push(value);
}
T pop()
{
T value = s1.pop();
if (value == min())
{
s2.pop();
}
return value;
}
T min()
{
if (s2.isEmpty())
{
return MAX_VALUE;
}
else {
return s2.peek();
}
}
T max()
{
if (s3.isEmpty())
{
return MIN_VALUE;
}
else
{
return s3.peek();
}
}
push(T值)
{
如果(值=max())
{
s3.推送(值);
}
s1.推力(值);
}
T pop()
{
T值=s1.pop();
如果(值==min())
{
s2.pop();
}
返回值;
}
T min()
{
if(s2.isEmpty())
{
返回最大值;
}
否则{
返回s2.peek();
}
}
T max()
{
if(s3.isEmpty())
{
返回最小值;
}
其他的
{
返回s3.peek();
}
}
请不要只要求我们为您解决问题。向我们展示你是如何试图自己解决问题的,然后向我们展示结果是什么,并告诉我们为什么你觉得它不起作用。请参阅“”,以获得一篇您确实需要阅读的优秀文章。@mohit我认为您的建议实际上是一个可能的答案。您只需在推送或弹出后更新max和min。看起来总体思路不错。显示您的代码(伪代码即可)。到底是什么不起作用?@n.m.更新了问题。Pop()
需要找到新的最小值或最大值存在问题-按照现在的方式,Pop()
不是O(1)操作。您可以通过向堆栈上的内容添加信息来解决此问题-堆栈没有理由只包含被推送的元素。在某个时间,最大值可能变为最小值。这个能考虑到吗?看起来很接近。push 0之后会发生什么;推100;推0;推100;流行音乐;pop
?@n.m.在所有4次按下后,最小堆栈将保持0,0(从下到上排序)。最大堆栈将容纳0、100、100。两次弹出后,最小堆栈将保持0。max堆栈将容纳0,100。@a hishekbansal如果堆栈只包含一个不同的值,则min==max总是这样。只有在将两个不同的值插入堆栈后,最小堆栈和最大堆栈才开始发散。啊,好的。上面写着“更大或相等”,我一定错过了“或相等”的部分。5:30:00Z vs 5:29:49Z。在你的评论和我的博文lol之间11秒。