📜  设计和实现特殊堆栈数据结构|新增空间优化版

📅  最后修改于: 2022-05-13 01:57:09.374000             🧑  作者: Mango

设计和实现特殊堆栈数据结构|新增空间优化版

问题:设计一个数据结构 SpecialStack,它支持所有堆栈操作,如 push()、pop()、isEmpty()、isFull() 和一个额外的操作 getMin(),它应该从 SpecialStack 返回最小元素。 SpecialStack 的所有这些操作都必须是 O(1)。要实现 SpecialStack,您应该只使用标准的 Stack 数据结构,而不要使用其他数据结构,如数组、列表、.等等。

例子:

Consider the following SpecialStack
16  --> TOP
15
29
19
18

When getMin() is called it should 
return 15, which is the minimum 
element in the current stack. 

If we do pop two times on stack, 
the stack becomes
29  --> TOP
19
18

When getMin() is called, it should 
return 18 which is the minimum in 
the current stack.

解决方案:使用两个堆栈:一个存储实际堆栈元素,另一个作为辅助堆栈存储最小值。想法是执行 push() 和 pop() 操作,使辅助堆栈的顶部始终是最小值。让我们看看 push() 和 pop() 操作是如何工作的。

Push(int x) // 将元素 x 插入到特殊堆栈
1) 将 x 推送到第一个堆栈(具有实际元素的堆栈)
2) 将 x 与第二个堆栈(辅助堆栈)的顶部元素进行比较。设顶部元素为 y。
.....a) 如果 x 小于 y,则将 x 推入辅助堆栈。
.....b) 如果 x 大于 y,则将 y 推入辅助堆栈。
int Pop() // 从特殊堆栈中移除一个元素并返回移除的元素
1)从辅助堆栈中弹出顶部元素。
2)从实际堆栈中弹出顶部元素并返回它。
步骤 1 是必要的,以确保辅助堆栈也为将来的操作更新。
int getMin() // 返回特殊堆栈中的最小元素
1) 返回辅助栈的顶部元素。

我们可以看到上述所有操作都是 O(1)
让我们看一个例子。让我们假设两个堆栈最初都是空的,并且将 18、19、29、15 和 16 插入到 SpecialStack 中。

When we insert 18, both stacks change to following.
Actual Stack
18 <--- top     
Auxiliary Stack
18 <---- top

When 19 is inserted, both stacks change to following.
Actual Stack
19 <--- top     
18
Auxiliary Stack
18 <---- top
18

When 29 is inserted, both stacks change to following.
Actual Stack
29 <--- top     
19
18
Auxiliary Stack
18 <---- top
18
18

When 15 is inserted, both stacks change to following.
Actual Stack
15 <--- top     
29
19 
18
Auxiliary Stack
15 <---- top
18
18
18

When 16 is inserted, both stacks change to following.
Actual Stack
16 <--- top     
15
29
19 
18
Auxiliary Stack
15 <---- top
15
18
18
18

以下是 SpecialStack 类的实现。在下面的实现中,SpecialStack 继承自 Stack 并且有一个 Stack 对象min作为辅助堆栈。

C++
#include 
#include 
 
using namespace std;
 
/* A simple stack class with
basic stack functionalities */
class Stack {
private:
    static const int max = 100;
    int arr[max];
    int top;
 
public:
    Stack() { top = -1; }
    bool isEmpty();
    bool isFull();
    int pop();
    void push(int x);
};
 
/* Stack's member method to check
if the stack is empty */
bool Stack::isEmpty()
{
    if (top == -1)
        return true;
    return false;
}
 
/* Stack's member method to check
if the stack is full */
bool Stack::isFull()
{
    if (top == max - 1)
        return true;
    return false;
}
 
/* Stack's member method to remove
an element from it */
int Stack::pop()
{
    if (isEmpty()) {
        cout << "Stack Underflow";
        abort();
    }
    int x = arr[top];
    top--;
    return x;
}
 
/* Stack's member method to insert
an element to it */
void Stack::push(int x)
{
    if (isFull()) {
        cout << "Stack Overflow";
        abort();
    }
    top++;
    arr[top] = x;
}
 
/* A class that supports all the stack
operations and one additional
  operation getMin() that returns the
minimum element from stack at
  any time.  This class inherits from
the stack class and uses an
  auxiliary stack that holds minimum
elements */
class SpecialStack : public Stack {
    Stack min;
 
public:
    int pop();
    void push(int x);
    int getMin();
};
 
/* SpecialStack's member method to insert
 an element to it. This method
   makes sure that the min stack is also
updated with appropriate minimum
   values */
void SpecialStack::push(int x)
{
    if (isEmpty() == true) {
        Stack::push(x);
        min.push(x);
    }
    else {
        Stack::push(x);
        int y = min.pop();
        min.push(y);
        if (x < y)
            min.push(x);
        else
            min.push(y);
    }
}
 
/* SpecialStack's member method to
remove an element from it. This method
   removes top element from min stack also. */
int SpecialStack::pop()
{
    int x = Stack::pop();
    min.pop();
    return x;
}
 
/* SpecialStack's member method to get
 minimum element from it. */
int SpecialStack::getMin()
{
    int x = min.pop();
    min.push(x);
    return x;
}
 
/* Driver program to test SpecialStack
 methods */
int main()
{
    SpecialStack s;
    s.push(10);
    s.push(20);
    s.push(30);
    cout << s.getMin() << endl;
    s.push(5);
    cout << s.getMin();
    return 0;
}


Java
// Java implementation of SpecialStack
// Note : here we use Stack class for
// Stack implementation
 
import java.util.Stack;
 
/* A class that supports all the
stack operations and one additional
operation getMin() that returns
the minimum element from stack at
any time. This class inherits from
the stack class and uses an
auxiliary stack that holds minimum
 elements */
 
class SpecialStack extends Stack {
    Stack min = new Stack<>();
 
    /* SpecialStack's member method to
insert an element to it. This method
    makes sure that the min stack is
also updated with appropriate minimum
    values */
    void push(int x)
    {
        if (isEmpty() == true) {
            super.push(x);
            min.push(x);
        }
        else {
            super.push(x);
            int y = min.pop();
            min.push(y);
            if (x < y)
                min.push(x);
            else
                min.push(y);
        }
    }
 
    /* SpecialStack's member method to
insert an element to it. This method
    makes sure that the min stack is
also updated with appropriate minimum
    values */
    public Integer pop()
    {
        int x = super.pop();
        min.pop();
        return x;
    }
 
    /* SpecialStack's member method to get
minimum element from it. */
    int getMin()
    {
        int x = min.pop();
        min.push(x);
        return x;
    }
 
    /* Driver program to test SpecialStack
methods */
    public static void main(String[] args)
    {
        SpecialStack s = new SpecialStack();
        s.push(10);
        s.push(20);
        s.push(30);
        System.out.println(s.getMin());
        s.push(5);
        System.out.println(s.getMin());
    }
}
// This code is contributed by Sumit Ghosh


Python3
# Python3 program for the
# above approach
# A simple stack class with 
# basic stack functionalities
class stack:
 
  def __init__(self):
 
    self.array = []
    self.top = -1
    self.max = 100 
 
  # Stack's member method to check
  # if the stack is empty
  def isEmpty(self):
 
    if self.top == -1:
      return True
    else:
      return False 
 
  # Stack's member method to check
  # if the stack is full 
  def isFull(self): 
     
    if self.top == self.max - 1:
      return True
    else:
      return False  
 
  # Stack's member method to
  # insert an element to it  
 
  def push(self, data):
 
    if self.isFull():
      print('Stack OverFlow')
      return
    else:
      self.top += 1
      self.array.append(data)    
 
  # Stack's member method to
  # remove an element from it
  def pop(self):
 
    if self.isEmpty():
      print('Stack UnderFlow')
      return
    else:
      self.top -= 1
      return self.array.pop()
 
# A class that supports all the stack 
# operations and one additional
# operation getMin() that returns the
# minimum element from stack at
# any time.  This class inherits from
# the stack class and uses an
# auxiliary stack that holds
# minimum elements 
class SpecialStack(stack):
 
  def __init__(self):
    super().__init__()
    self.Min = stack() 
 
  # SpecialStack's member method to
  # insert an element to it. This method
  # makes sure that the min stack is also
  # updated with appropriate minimum
  # values
  def push(self, x):
 
    if self.isEmpty():
      super().push(x)
      self.Min.push(x)
    else:
      super().push(x)
      y = self.Min.pop()
      self.Min.push(y)
      if x <= y:
        self.Min.push(x)
      else:
        self.Min.push(y) 
 
  # SpecialStack's member method to 
  # remove an element from it. This
  # method removes top element from
  # min stack also.
  def pop(self):
 
    x = super().pop()
    self.Min.pop()
    return x 
 
  # SpecialStack's member method
  # to get minimum element from it.
  def getmin(self):
 
    x = self.Min.pop()
    self.Min.push(x)
    return x
 
# Driver code
if __name__ == '__main__':
   
  s = SpecialStack()
  s.push(10)
  s.push(20)
  s.push(30)
  print(s.getmin())
  s.push(5)
  print(s.getmin())
 
# This code is contributed by rachitkatiyar99


C++
/* SpecialStack's member method to
   insert an element to it. This method
   makes sure that the min stack is
   also updated with appropriate minimum
   values */
void SpecialStack::push(int x)
{
    if (isEmpty() == true) {
        Stack::push(x);
        min.push(x);
    }
    else {
        Stack::push(x);
        int y = min.pop();
        min.push(y);
 
        /* push only when the incoming element
           of main stack is smaller
        than or equal to top of auxiliary stack */
        if (x <= y)
            min.push(x);
    }
}
 
/* SpecialStack's member method to
   remove an element from it. This method
   removes top element from min stack also. */
int SpecialStack::pop()
{
    int x = Stack::pop();
    int y = min.pop();
 
    /* Push the popped element y back
       only if it is not equal to x */
    if (y != x)
        min.push(y);
 
    return x;
}


Java
/* SpecialStack's member method to
insert an element to it. This method
makes sure that the min stack is
also updated with appropriate minimum
values */
 
void push(int x)
{
    if (isEmpty() == true) {
        super.push(x);
        min.push(x);
    }
    else {
        super.push(x);
        int y = min.pop();
        min.push(y);
 
        /* push only when the incoming
           element of main stack is smaller
        than or equal to top of auxiliary stack */
        if (x <= y)
            min.push(x);
    }
}
 
/* SpecialStack's member method to
   remove an element from it. This method
   removes top element from min stack also. */
public Integer pop()
{
    int x = super.pop();
    int y = min.pop();
 
    /* Push the popped element y back
       only if it is not equal to x */
    if (y != x)
        min.push(y);
    return x;
}
 
// This code is contributed by Sumit Ghosh


Python3
''' SpecialStack's member method to
insert an element to it. This method
makes sure that the min stack is
also updated with appropriate minimum
values '''
 
def push(x):
    if (isEmpty() == True):
        super.append(x);
        min.append(x);
     
    else:
        super.append(x);
        y = min.pop();
        min.append(y);
 
        ''' push only when the incoming
           element of main stack is smaller
        than or equal to top of auxiliary stack '''
        if (x <= y):
            min.append(x);
     
 
 
''' SpecialStack's member method to
   remove an element from it. This method
   removes top element from min stack also. '''
def pop():
    x = super.pop();
    y = min.pop();
 
    ''' Push the popped element y back
       only if it is not equal to x '''
    if (y != x):
        min.append(y);
    return x;
 
 
# This code contributed by umadevi9616


C#
/* SpecialStack's member method to
insert an element to it. This method
makes sure that the min stack is
also updated with appropriate minimum
values */
 
void push(int x)
{
    if (min.Count==0) {
        super.Push(x);
        min.Push(x);
    }
    else {
        super.Push(x);
        int y = min.Pop();
        min.Push(y);
 
        /* push only when the incoming
           element of main stack is smaller
        than or equal to top of auxiliary stack */
        if (x <= y)
            min.Push(x);
    }
}
 
/* SpecialStack's member method to
   remove an element from it. This method
   removes top element from min stack also. */
public int pop()
{
    int x = super.Pop();
    int y = min.Pop();
 
    /* Push the popped element y back
       only if it is not equal to x */
    if (y != x)
        min.Push(y);
    return x;
}
 
// This code is contributed by umadevi9616


Javascript


C++
#include 
#include 
#include 
using namespace std;
 
/* A special stack having peek() pop() and
 * push() along with additional getMin() that
 * returns minimum value in a stack without
 * using extra space and all operations in O(1)
 * time.. ???? */
class SpecialStack
{
     
    // Sentinel value for min
    int min = -1; 
     
    // DEMO_VALUE
    static const int demoVal = 9999;
    stack st;
 
public:
 
    void getMin()
    {
        cout << "min is: " << min << endl;
    }
 
    void push(int val)
    {
         
        // If stack is empty OR current element
        // is less than min, update min.
        if (st.empty() || val < min)
        {
            min = val;
        }
         
        // Encode the current value with
        // demoVal, combine with min and
        // insert into stack
        st.push(val * demoVal + min);
        cout << "pushed: " << val << endl;
    }
 
    int pop()
    {   
        // if stack is empty return -1;
        if ( st.empty() ) {
          cout << "stack underflow" << endl ;
          return -1;
        }
       
        int val = st.top();
        st.pop();
         
        // If stack is empty, there would
        // be no min value present, so
        // make min as -1
        if (!st.empty())
            min = st.top() % demoVal;
        else
            min = -1;
             
        cout << "popped: " << val / demoVal << endl;
         
        // Decode actual value from
        // encoded value
        return val / demoVal;
    }
 
    int peek()
    {
         
        // Decode actual value
        // from encoded value
        return st.top() / demoVal;
    }
};
 
// Driver Code
int main()
{
    SpecialStack s;
 
    vector arr = { 3, 2, 6, 1, 8, 5, 5, 5, 5 };
 
    for(int i = 0; i < arr.size(); i++)
    {
        s.push(arr[i]);
        s.getMin();
    }
     
    cout << endl;
    for(int i = 0; i < arr.size(); i++)
    {
        s.pop();
        s.getMin();
    }
    return 0;
}
 
// This code is contributed by scisaif


Java
import java.util.Stack;
 
/* A special stack having peek() pop() and push() along with
 * additional getMin() that returns minimum value in a stack
 * without using extra space and all operations in O(1)
 * time.. 🙂
 * */
public class SpecialStack {
 
    int min = -1; // sentinel value for min
    static int demoVal = 9999; // DEMO_VALUE
    Stack st = new Stack();
 
    void getMin() { System.out.println("min is: " + min); }
 
    void push(int val)
    {
        // if stack is empty OR current element is less than
        // min, update min..
        if (st.isEmpty() || val < min) {
            min = val;
        }
 
        st.push(val * demoVal
                + min); // encode the current value with
                        // demoVal, combine with min and
                        // insert into stack
        System.out.println("pushed: " + val);
    }
 
    int pop()
    {   
        // if stack is empty return -1;
        if (st.isEmpty() ) {
             System.out.println("stack underflow");
               return -1;
          }
       
        int val = st.pop();
 
        if (!st.isEmpty()) // if stack is empty, there would
                           // be no min value present, so
                           // make min as -1
            min = st.peek() % demoVal;
        else
            min = -1;
        System.out.println("popped: " + val / demoVal);
        return val / demoVal; // decode actual value from
                              // encoded value
    }
 
    int peek()
    {
        return st.peek() / demoVal; // decode actual value
                                    // from encoded value
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        SpecialStack s = new SpecialStack();
 
        int[] arr = { 3, 2, 6, 1, 8, 5, 5, 5, 5 };
 
        for (int i = 0; i < arr.length; i++) {
            s.push(arr[i]);
            s.getMin();
        }
        System.out.println();
        for (int i = 0; i < arr.length; i++) {
            s.pop();
            s.getMin();
        }
    }
}


C#
using System;
using System.Collections.Generic;
 
 
/* A special stack having peek() pop() and push() along with
 * additional getMin() that returns minimum value in a stack
 * without using extra space and all operations in O(1)
 * time.. 🙂
 * */
public class SpecialStack {
 
    int min = -1; // sentinel value for min
    static int demoVal = 9999; // DEMO_VALUE
    Stack st = new Stack();
 
    void getMin() { Console.WriteLine("min is: " + min); }
 
    void push(int val)
    {
        // if stack is empty OR current element is less than
        // min, update min..
        if (st.Count==0 || val < min) {
            min = val;
        }
 
        st.Push(val * demoVal
                + min); // encode the current value with
                        // demoVal, combine with min and
                        // insert into stack
        Console.WriteLine("pushed: " + val);
    }
 
    int pop()
    {   
        // if stack is empty return -1;
        if (st.Count==0 ) {
             Console.WriteLine("stack underflow");
               return -1;
          }
       
        int val = st.Pop();
 
        if (st.Count!=0) // if stack is empty, there would
                           // be no min value present, so
                           // make min as -1
            min = st.Peek() % demoVal;
        else
            min = -1;
        Console.WriteLine("popped: " + val / demoVal);
        return val / demoVal; // decode actual value from
                              // encoded value
    }
 
    int peek()
    {
        return st.Peek() / demoVal; // decode actual value
                                    // from encoded value
    }
 
    // Driver Code
    public static void Main(String[] args)
    {
        SpecialStack s = new SpecialStack();
 
        int[] arr = { 3, 2, 6, 1, 8, 5, 5, 5, 5 };
 
        for (int i = 0; i < arr.Length; i++) {
            s.push(arr[i]);
            s.getMin();
        }
        Console.WriteLine();
        for (int i = 0; i < arr.Length; i++) {
            s.pop();
            s.getMin();
        }
    }
}
 
// This code is contributed by gauravrajput1


输出
10
5

复杂性分析:

  • 时间复杂度:
    1. 对于插入操作:O(1) (因为在堆栈中插入“推送”需要恒定时间)
    2. 对于删除操作:O(1) (因为堆栈中的删除“弹出”需要恒定时间)
    3. 对于“Get Min”操作:O(1) (因为我们使用了一个辅助堆栈,它的顶部作为最小元素)
  • 辅助空间: O(n)。
    使用辅助堆栈来存储值。

空间优化版
上述方法可以优化。我们可以限制辅助堆栈中的元素数量。只有当主栈的传入元素小于或等于辅助栈的顶部时,我们才能push。同样在弹出时,如果弹出元素等于辅助栈的顶部,则移除辅助栈的顶部元素。以下是 push() 和 pop() 的修改实现。

C++

/* SpecialStack's member method to
   insert an element to it. This method
   makes sure that the min stack is
   also updated with appropriate minimum
   values */
void SpecialStack::push(int x)
{
    if (isEmpty() == true) {
        Stack::push(x);
        min.push(x);
    }
    else {
        Stack::push(x);
        int y = min.pop();
        min.push(y);
 
        /* push only when the incoming element
           of main stack is smaller
        than or equal to top of auxiliary stack */
        if (x <= y)
            min.push(x);
    }
}
 
/* SpecialStack's member method to
   remove an element from it. This method
   removes top element from min stack also. */
int SpecialStack::pop()
{
    int x = Stack::pop();
    int y = min.pop();
 
    /* Push the popped element y back
       only if it is not equal to x */
    if (y != x)
        min.push(y);
 
    return x;
}

Java

/* SpecialStack's member method to
insert an element to it. This method
makes sure that the min stack is
also updated with appropriate minimum
values */
 
void push(int x)
{
    if (isEmpty() == true) {
        super.push(x);
        min.push(x);
    }
    else {
        super.push(x);
        int y = min.pop();
        min.push(y);
 
        /* push only when the incoming
           element of main stack is smaller
        than or equal to top of auxiliary stack */
        if (x <= y)
            min.push(x);
    }
}
 
/* SpecialStack's member method to
   remove an element from it. This method
   removes top element from min stack also. */
public Integer pop()
{
    int x = super.pop();
    int y = min.pop();
 
    /* Push the popped element y back
       only if it is not equal to x */
    if (y != x)
        min.push(y);
    return x;
}
 
// This code is contributed by Sumit Ghosh

Python3

''' SpecialStack's member method to
insert an element to it. This method
makes sure that the min stack is
also updated with appropriate minimum
values '''
 
def push(x):
    if (isEmpty() == True):
        super.append(x);
        min.append(x);
     
    else:
        super.append(x);
        y = min.pop();
        min.append(y);
 
        ''' push only when the incoming
           element of main stack is smaller
        than or equal to top of auxiliary stack '''
        if (x <= y):
            min.append(x);
     
 
 
''' SpecialStack's member method to
   remove an element from it. This method
   removes top element from min stack also. '''
def pop():
    x = super.pop();
    y = min.pop();
 
    ''' Push the popped element y back
       only if it is not equal to x '''
    if (y != x):
        min.append(y);
    return x;
 
 
# This code contributed by umadevi9616

C#

/* SpecialStack's member method to
insert an element to it. This method
makes sure that the min stack is
also updated with appropriate minimum
values */
 
void push(int x)
{
    if (min.Count==0) {
        super.Push(x);
        min.Push(x);
    }
    else {
        super.Push(x);
        int y = min.Pop();
        min.Push(y);
 
        /* push only when the incoming
           element of main stack is smaller
        than or equal to top of auxiliary stack */
        if (x <= y)
            min.Push(x);
    }
}
 
/* SpecialStack's member method to
   remove an element from it. This method
   removes top element from min stack also. */
public int pop()
{
    int x = super.Pop();
    int y = min.Pop();
 
    /* Push the popped element y back
       only if it is not equal to x */
    if (y != x)
        min.Push(y);
    return x;
}
 
// This code is contributed by umadevi9616

Javascript


复杂性分析:

  • 时间复杂度:
    1. 对于插入操作:O(1) (因为在堆栈中插入“推送”需要恒定时间)
    2. 对于删除操作:O(1) (因为堆栈中的删除“弹出”需要恒定时间)
    3. 对于“获取最小值”操作:O(1) (因为我们使用了一个辅助函数,它的顶部作为最小元素)
  • 辅助空间: O(n)。
    最坏情况下的复杂性与上述相同,但在其他情况下,由于忽略了重复,它将比上述方法占用的空间略少。

进一步优化 O(1) 时间复杂度和 O(1) 空间复杂度解决方案:
上述方法可以进一步优化,解决方案可以在 O(1) 时间复杂度和 O(1) 空间复杂度下工作。这个想法是存储最小元素直到当前插入)以及所有元素作为 DUMMY_VALUE 的提醒,并将实际元素存储为 DUMMY_VALUE 的倍数。
例如,在将元素 'e' 推入堆栈时,将其存储为(e * DUMMY_VALUE + minFoundSoFar) ,这样我们就知道在插入 'e' 时堆栈中存在的最小值是多少。

要弹出实际值,只需返回 e/DUMMY_VALUE 并将新的最小值设置为(minFoundSoFar % DUMMY_VALUE)

注意:如果我们尝试在堆栈中插入 DUMMY_VALUE,以下方法将失败,因此我们必须仔细选择 DUMMY_VALUE。
假设以下元素被插入到堆栈中 - 3 2 6 1 8 5

d是虚拟值。

s是包装堆栈

top是栈顶元素

min 是插入/删除元素时的最小值

以下步骤显示了上述变量在任何时刻的当前状态——

C++

#include 
#include 
#include 
using namespace std;
 
/* A special stack having peek() pop() and
 * push() along with additional getMin() that
 * returns minimum value in a stack without
 * using extra space and all operations in O(1)
 * time.. ???? */
class SpecialStack
{
     
    // Sentinel value for min
    int min = -1; 
     
    // DEMO_VALUE
    static const int demoVal = 9999;
    stack st;
 
public:
 
    void getMin()
    {
        cout << "min is: " << min << endl;
    }
 
    void push(int val)
    {
         
        // If stack is empty OR current element
        // is less than min, update min.
        if (st.empty() || val < min)
        {
            min = val;
        }
         
        // Encode the current value with
        // demoVal, combine with min and
        // insert into stack
        st.push(val * demoVal + min);
        cout << "pushed: " << val << endl;
    }
 
    int pop()
    {   
        // if stack is empty return -1;
        if ( st.empty() ) {
          cout << "stack underflow" << endl ;
          return -1;
        }
       
        int val = st.top();
        st.pop();
         
        // If stack is empty, there would
        // be no min value present, so
        // make min as -1
        if (!st.empty())
            min = st.top() % demoVal;
        else
            min = -1;
             
        cout << "popped: " << val / demoVal << endl;
         
        // Decode actual value from
        // encoded value
        return val / demoVal;
    }
 
    int peek()
    {
         
        // Decode actual value
        // from encoded value
        return st.top() / demoVal;
    }
};
 
// Driver Code
int main()
{
    SpecialStack s;
 
    vector arr = { 3, 2, 6, 1, 8, 5, 5, 5, 5 };
 
    for(int i = 0; i < arr.size(); i++)
    {
        s.push(arr[i]);
        s.getMin();
    }
     
    cout << endl;
    for(int i = 0; i < arr.size(); i++)
    {
        s.pop();
        s.getMin();
    }
    return 0;
}
 
// This code is contributed by scisaif

Java

import java.util.Stack;
 
/* A special stack having peek() pop() and push() along with
 * additional getMin() that returns minimum value in a stack
 * without using extra space and all operations in O(1)
 * time.. 🙂
 * */
public class SpecialStack {
 
    int min = -1; // sentinel value for min
    static int demoVal = 9999; // DEMO_VALUE
    Stack st = new Stack();
 
    void getMin() { System.out.println("min is: " + min); }
 
    void push(int val)
    {
        // if stack is empty OR current element is less than
        // min, update min..
        if (st.isEmpty() || val < min) {
            min = val;
        }
 
        st.push(val * demoVal
                + min); // encode the current value with
                        // demoVal, combine with min and
                        // insert into stack
        System.out.println("pushed: " + val);
    }
 
    int pop()
    {   
        // if stack is empty return -1;
        if (st.isEmpty() ) {
             System.out.println("stack underflow");
               return -1;
          }
       
        int val = st.pop();
 
        if (!st.isEmpty()) // if stack is empty, there would
                           // be no min value present, so
                           // make min as -1
            min = st.peek() % demoVal;
        else
            min = -1;
        System.out.println("popped: " + val / demoVal);
        return val / demoVal; // decode actual value from
                              // encoded value
    }
 
    int peek()
    {
        return st.peek() / demoVal; // decode actual value
                                    // from encoded value
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        SpecialStack s = new SpecialStack();
 
        int[] arr = { 3, 2, 6, 1, 8, 5, 5, 5, 5 };
 
        for (int i = 0; i < arr.length; i++) {
            s.push(arr[i]);
            s.getMin();
        }
        System.out.println();
        for (int i = 0; i < arr.length; i++) {
            s.pop();
            s.getMin();
        }
    }
}

C#

using System;
using System.Collections.Generic;
 
 
/* A special stack having peek() pop() and push() along with
 * additional getMin() that returns minimum value in a stack
 * without using extra space and all operations in O(1)
 * time.. 🙂
 * */
public class SpecialStack {
 
    int min = -1; // sentinel value for min
    static int demoVal = 9999; // DEMO_VALUE
    Stack st = new Stack();
 
    void getMin() { Console.WriteLine("min is: " + min); }
 
    void push(int val)
    {
        // if stack is empty OR current element is less than
        // min, update min..
        if (st.Count==0 || val < min) {
            min = val;
        }
 
        st.Push(val * demoVal
                + min); // encode the current value with
                        // demoVal, combine with min and
                        // insert into stack
        Console.WriteLine("pushed: " + val);
    }
 
    int pop()
    {   
        // if stack is empty return -1;
        if (st.Count==0 ) {
             Console.WriteLine("stack underflow");
               return -1;
          }
       
        int val = st.Pop();
 
        if (st.Count!=0) // if stack is empty, there would
                           // be no min value present, so
                           // make min as -1
            min = st.Peek() % demoVal;
        else
            min = -1;
        Console.WriteLine("popped: " + val / demoVal);
        return val / demoVal; // decode actual value from
                              // encoded value
    }
 
    int peek()
    {
        return st.Peek() / demoVal; // decode actual value
                                    // from encoded value
    }
 
    // Driver Code
    public static void Main(String[] args)
    {
        SpecialStack s = new SpecialStack();
 
        int[] arr = { 3, 2, 6, 1, 8, 5, 5, 5, 5 };
 
        for (int i = 0; i < arr.Length; i++) {
            s.push(arr[i]);
            s.getMin();
        }
        Console.WriteLine();
        for (int i = 0; i < arr.Length; i++) {
            s.pop();
            s.getMin();
        }
    }
}
 
// This code is contributed by gauravrajput1
输出
pushed: 3
min is: 3
pushed: 2
min is: 2
pushed: 6
min is: 2
pushed: 1
min is: 1
pushed: 8
min is: 1
pushed: 5
min is: 1
pushed: 5
min is: 1
pushed: 5
min is: 1
pushed: 5
min is: 1

popped: 5
min is: 1
popped: 5
min is: 1
popped: 5
min is: 1
popped: 5
min is: 1
popped: 8
min is: 1
popped: 1
min is: 2
popped: 6
min is: 2
popped: 2
min is: 3
popped: 3
min is: -1

复杂性分析:

对于 push() 操作: O(1)(因为在堆栈中插入“push”需要恒定时间)
对于 pop() 操作: O(1)(因为堆栈中的弹出操作需要恒定时间)

对于“Get Min”操作: O(1)(因为我们在整个代码中都维护了 min 变量)

辅助空间: O(1)。没有使用额外的空间。