使用一个固定大小的数组可以有效地实现两个堆栈:堆栈#1从左端开始向右增长,而堆栈#2从右端开始向左增长。三个堆栈是否可能相同?
更具体地说,在以下条件下是否可以实现三个堆栈:
- 您有一个固定大小的数组,可以容纳N个对象。
- 只要这三个堆栈大小之和小于N,push()就不会失败。
- push()和pop()操作都应花费O(1)时间。
- 除了数组之外,您只能使用O(1)额外的空间。
这里是指那些解决方案的例子并不满足这些要求:
- 将数组拆分为3个固定部分,并将每个部分用于堆栈(违反2)。
- 与上述类似,但堆栈之间有可移动的边界(违反3)。
- 基于简单链表的实现(违反4)。
即使它们不能完全满足所有条件(1)-(4),我也会接受非平凡的算法或不可能证明,例如,推/弹出需要O(1)摊销时间的算法,或者额外的内存小于O(N),例如O(log N)。或者说不可能的证据表明,例如,每个推送/弹出操作访问少于5个数组元素是不可能的。
1
我不知道您是否认为这违反了要求4,但是如果N个对象数组中的每个“对象”都可以包含一个附加字段(例如整数索引),那么您可以在数组内部实现“链接列表” 。您可以使用3个外部变量保存3个堆栈中每个堆栈的顶部索引,每个“对象”可以指向其堆栈中的上一个元素。
—
阿维塔尔(Avi Tal)
“对象”是指push()接受并pop()返回的事物。从堆栈实现的角度来看,它们只是不透明的数据块(例如,一个对象可以是32位整数)。堆栈实现不应以任何方式修改这些对象。
—
user1020406
考虑您首先执行推操作序列,然后仅执行弹出操作。关于此版本的问题是否已知?
—
Dmitri Urbanowicz
将的额外空间,你满意吗?
—
Dmitri Urbanowicz '19年
回复:“先推后推N次”版本:我不知道,但是即使将其识别为一个有趣的子问题也是有用的,因为即使不清楚O(1)解决方案是否可行。有关上限,请参见@Alexei的答案及其注释线程。至于解决方案,是的,我接受。我是刚开始在stackexchange上发布问题的新手,所以我不确定如何处理随着时间的推移可以提供越来越好的解决方案的情况。我见过的一种方法是等待一天左右才能接受答案,以防出现更好的情况,所以我会这样做。
—
user1020406