在 O(1) 时间内检索堆栈中的 Min 元素

Posted

技术标签:

【中文标题】在 O(1) 时间内检索堆栈中的 Min 元素【英文标题】:Retrieving the Min element in a stack in O(1) Time 【发布时间】:2012-10-24 18:50:35 【问题描述】:

我问这个问题的原因是因为我不明白为什么我认为的方式不能应用于这个特定问题

“你将如何设计一个堆栈, 除了push和pop,还有一个函数min,它返回最小元素? push、pop 和 min 都应该在 O(1) 时间内运行"

我的基本解决方案:如果我们在 stack 类中有一个变量,那么当我们将一个项目推入堆栈时,我们会检查它是否有可能比我们的 min 变量。如果是赋值给最小值,如果不是忽略。

你仍然会得到 O(1),就像 min 函数一样;

int getMinimum()
  return min;

为什么从来没有提到过这个解决方案,或者我的想法有什么问题?

【问题讨论】:

如果最小元素从堆栈中弹出怎么办?您如何在 O(1) 时间内找到新的最小值? @SebastianPaaskeTørholm 非常感谢。我现在明白了 design a stack such that getMinimum( ) should be O(1) 的可能重复项 【参考方案1】:

如果您从堆栈中弹出数字,这将不起作用。

例如。 2,4,5,3,1。在您弹出 1 次后,您的最低限度是多少?

解决方案是保留一堆最小值,而不仅仅是一个值。如果遇到小于等于当前最小值的值,则需要将其压入最小堆栈。

例如

Push(4):
Stack: 4
Min-stack: 4

Push(2):
Stack: 4 2
Min-stack: 4 2

Push(2):
Stack: 4 2 2
Min-stack: 4 2 2

Push(5):
Stack: 4 2 2 5
Min-stack: 4 2 2

Push(3):
Stack: 4 2 2 5 3
Min-stack: 4 2 2

Push(1):
Stack: 4 2 2 5 3 1
Min-stack: 4 2 2 1

Pop():
Stack: 4 2 2 5 3
Min-stack: 4 2 2

Pop():
Stack: 4 2 2 5
Min-stack: 4 2 2

Pop():
Stack: 4 2 2
Min-stack: 4 2 2

Pop():
Stack: 4 2
Min-stack: 4 2

Pop():
Stack: 4
Min-stack: 4

【讨论】:

非常感谢!终于明白了。 当然。时间结束后:D 您还需要将相等的元素推送到最小堆栈。我不确定您是否有意这样做,但应该明确提及。 好电话。我想保持我的例子简短,但我会添加它。【参考方案2】:

我找到了这个解决方案here

struct StackGetMin 
  void push(int x) 
    elements.push(x);
    if (minStack.empty() || x <= minStack.top())
      minStack.push(x);
  
  bool pop() 
    if (elements.empty()) return false;
    if (elements.top() == minStack.top())
      minStack.pop();
    elements.pop();
    return true;
  
  bool getMin(int &min) 
    if (minStack.empty()) 
      return false;
     else 
      min = minStack.top();
      return true;
    
  
  stack<int> elements;
  stack<int> minStack;
;

【讨论】:

【参考方案3】:

使用链表来跟踪将成为头部的最小值。

请注意,linkedlist.app= append(我们将值放在尾部)。 linkedlist.pre =prepend(我们把值作为链表的头部)

公共类堆栈

int[] elements;
int top;
Linkedlists min;

public Stack(int n) 
    elements = new int[n];
    top = 0;
    min = new Linkedlists();


public void realloc(int n) 
    int[] tab = new int[n];
    for (int i = 0; i < top; i++) 
        tab[i] = elements[i];
    

    elements = tab;


public void push(int x) 
    if (top == elements.length) 
        realloc(elements.length * 2);
    
    if (top == 0) 
        min.pre(x);
     else if (x < min.head.data) 
        min.pre(x);
     else 
        min.app(x);
    
    elements[top++] = x;


public int pop() 

    int x = elements[--top];
    if (top == 0) 

    
    if (this.getMin() == x) 
        min.head = min.head.next;
    
    elements[top] = 0;
    if (4 * top < elements.length) 
        realloc((elements.length + 1) / 2);
    

    return x;


public void display() 
    for (Object x : elements) 
        System.out.print(x + " ");
    



public int getMin() 
    if (top == 0) 
        return 0;
    
    return this.min.head.data;


public static void main(String[] args) 
    Stack stack = new Stack(4);
    stack.push(2);
    stack.push(3);
    stack.push(1);
    stack.push(4);
    stack.push(5);
    stack.pop();
    stack.pop();
    stack.pop();
    stack.push(1);
    stack.pop();
    stack.pop();
    stack.pop();
    stack.push(2);
    System.out.println(stack.getMin());
    stack.display();


【讨论】:

以上是关于在 O(1) 时间内检索堆栈中的 Min 元素的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode算法题-Min Stack(Java实现)

剑指:包含min函数的栈(min栈)

单调栈

将 find-min/find-max 堆栈推广到任意顺序统计?

有没有办法在少于 O(n) 的时间内找到集合中的最小元素?

堆栈-155-最小栈