如果您最初假设插入和删除是 O(1) 复杂性(如果您只想插入顶部并从顶部删除/弹出,那么堆栈可以正常工作),那么为了让 getMin 返回最小值在恒定时间内,您需要以某种方式存储最小值。如果您只有一个成员变量来跟踪 min 那么如果将其从堆栈中删除会发生什么?您将需要下一个最小值,或相对于堆栈中剩余内容的最小值。为此,您可以让堆栈中的元素包含它认为的最小值。堆栈在代码中由链表表示,因此链表中节点的结构如下所示:
struct Node
{
int value;
int min;
Node *next;
}
如果您查看示例列表:7->3->1->5->2。让我们看看这将如何构建。首先将值 2 推入(到空堆栈),这是最小值,因为它是第一个数字,跟踪它并在构造它时将其添加到节点:{2, 2}。然后你将 5 压入堆栈,5>2 所以最小值是相同的压入 {5,2},现在你有 {5,2}->{2,2}。然后你推入 1,1<2 所以新的最小值是 1,推 {1, 1},现在是 {1,1}->{5,2}->{2,2} 等等。到最后你有:
{7,1}->{3,1}->{1,1}->{5,2}->{2,2}
在这个实现中,如果你弹出 7、3 和 1,你的新最小值应该是 2。而且您的所有操作仍处于恒定时间,因为您只是向节点添加了一个比较和另一个值。(您可以使用 C++ 的 peek() 之类的东西,或者只使用指向列表头部的指针来查看堆栈顶部并在那里获取最小值,它会在恒定时间内为您提供堆栈的最小值)。
这个实现的一个折衷是你的节点中有一个额外的整数,如果你在一个非常大的列表中只有一两分钟,那就是浪费内存。如果是这种情况,那么您可以在单独的堆栈中跟踪分钟,只需将要删除的节点的值与该列表的顶部进行比较,如果匹配,则将其从两个列表中删除。要跟踪的事情更多,因此这实际上取决于情况。
免责声明:这是我在这个论坛上的第一篇文章,所以如果它有点令人费解或罗嗦,我很抱歉。我也不是说这是“一个真实的答案”,而是我认为最简单且符合问题要求的答案。总是有权衡,根据情况需要不同的方法。