Design a stack that supports getMin() in O(1) time and O(1) extra space - GeeksforGeeks

11 May, 2022
Question: Design a Data Structure SpecialStack that supports all the stack operations like push(), pop(), isEmpty(), isFull() and an additional operation getMin() which should return minimum element from the SpecialStack. All these operations of SpecialStack must be O(1). To implement SpecialStack, you should only use standard Stack data structure and no other data structure like arrays, list, .. etc
Example:  
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.
 
An approach that uses O(1) time and O(n) extra space is discussed here.In this article, a new approach is discussed that supports minimum with O(1) extra space. We define a variable minEle that stores the current minimum element in the stack. Now the interesting part is, how to handle the case when minimum element is removed. To handle this, we push “2x – minEle” into the stack instead of x so that previous minimum element can be retrieved using current minEle and its value stored in stack. Below are detailed steps and explanation of working.Push(x) : Inserts x at the top of stack.  
If stack is empty, insert x into the stack and make minEle equal to x.
If stack is not empty, compare x with minEle. Two cases arise:If x is greater than or equal to minEle, simply insert x.If x is less than minEle, insert (2*x – minEle) into the stack and make minEle equal to x. For example, let previous minEle was 3. Now we want to insert 2. We update minEle as 2 and insert 2*2 – 3 = 1 into the stack.
If x is greater than or equal to minEle, simply insert x.
If x is less than minEle, insert (2*x – minEle) into the stack and make minEle equal to x. For example, let previous minEle was 3. Now we want to insert 2. We update minEle as 2 and insert 2*2 – 3 = 1 into the stack.
Pop() : Removes an element from top of stack.  
Remove element from top. Let the removed element be y. Two cases arise:If y is greater than or equal to minEle, the minimum element in the stack is still minEle.If y is less than minEle, the minimum element now becomes (2*minEle – y), so update (minEle = 2*minEle – y). This is where we retrieve previous minimum from current minimum and its value in stack. For example, let the element to be removed be 1 and minEle be 2. We remove 1 and update minEle as 2*2 – 1 = 3.
If y is greater than or equal to minEle, the minimum element in the stack is still minEle.
If y is less than minEle, the minimum element now becomes (2*minEle – y), so update (minEle = 2*minEle – y). This is where we retrieve previous minimum from current minimum and its value in stack. For example, let the element to be removed be 1 and minEle be 2. We remove 1 and update minEle as 2*2 – 1 = 3.
Important Points:  
Stack doesn’t hold actual value of an element if it is minimum so far.
Actual minimum element is always stored in minEle
Illustration  
Push(x)  
 
Number to be Inserted: 3, Stack is empty, so insert 3 into stack and minEle = 3.
Number to be Inserted: 5, Stack is not empty, 5> minEle, insert 5 into stack and minEle = 3.
Number to be Inserted: 2, Stack is not empty, 2< minEle, insert (2*2-3 = 1) into stack and minEle = 2.
Number to be Inserted: 1, Stack is not empty, 1< minEle, insert (2*1-2 = 0) into stack and minEle = 1.
Number to be Inserted: 1, Stack is not empty, 1 = minEle, insert 1 into stack and minEle = 1.
Number to be Inserted: -1, Stack is not empty, -1 < minEle, insert (2*-1 – 1 = -3) into stack and minEle = -1.
 
Pop()  
 
Initially the minimum element minEle in the stack is -1.
Number removed: -3, Since -3 is less than the minimum element the original number being removed is minEle which is -1, and the new minEle = 2*-1 – (-3) = 1
Number removed: 1, 1 == minEle, so number removed is 1 and minEle is still equal to 1.
Number removed: 0, 0< minEle, original number is minEle which is 1 and new minEle = 2*1 – 0 = 2.
Number removed: 1, 1< minEle, original number is minEle which is 2 and new minEle = 2*2 – 1 = 3.
Number removed: 5, 5> minEle, original number is 5 and minEle is still 3
 
C++
Java
Python 3
C#
// C++ program to implement a stack that supports// getMinimum() in O(1) time and O(1) extra space.#include <bits/stdc++.h>using namespace std;  // A user defined stack that supports getMin() in// addition to push() and pop()struct MyStack{    stack<int> s;    int minEle;      // Prints minimum element of MyStack    void getMin()    {        if (s.empty())            cout << "Stack is empty\n";          // variable minEle stores the minimum element        // in the stack.        else            cout <<"Minimum Element in the stack is: "                 << minEle << "\n";    }      // Prints top element of MyStack    void peek()    {        if (s.empty())        {            cout << "Stack is empty ";            return;        }          int t = s.top(); // Top element.          cout << "Top Most Element is: ";          // If t < minEle means minEle stores        // value of t.        (t < minEle)? cout << minEle: cout << t;    }      // Remove the top element from MyStack    void pop()    {        if (s.empty())        {            cout << "Stack is empty\n";            return;        }          cout << "Top Most Element Removed: ";        int t = s.top();        s.pop();          // Minimum will change as the minimum element        // of the stack is being removed.        if (t < minEle)        {            cout << minEle << "\n";            minEle = 2*minEle - t;        }          else            cout << t << "\n";    }      // Removes top element from MyStack    void push(int x)    {        // Insert new number into the stack        if (s.empty())        {            minEle = x;            s.push(x);            cout <<  "Number Inserted: " << x << "\n";            return;        }          // If new number is less than minEle        else if (x < minEle)        {            s.push(2*x - minEle);            minEle = x;        }          else           s.push(x);          cout <<  "Number Inserted: " << x << "\n";    }};  // Driver Codeint main(){    MyStack s;    s.push(3);    s.push(5);    s.getMin();    s.push(2);    s.push(1);    s.getMin();    s.pop();    s.getMin();    s.pop();    s.peek();      return 0;}
// Java program to implement a stack that supports// getMinimum() in O(1) time and O(1) extra space.import java.util.*;  // A user defined stack that supports getMin() in// addition to push() and pop()class MyStack{    Stack<Integer> s;    Integer minEle;      // Constructor    MyStack() { s = new Stack<Integer>(); }      // Prints minimum element of MyStack    void getMin()    {        // Get the minimum number in the entire stack        if (s.isEmpty())            System.out.println("Stack is empty");          // variable minEle stores the minimum element        // in the stack.        else            System.out.println("Minimum Element in the " +                               " stack is: " + minEle);    }      // prints top element of MyStack    void peek()    {        if (s.isEmpty())        {            System.out.println("Stack is empty ");            return;        }          Integer t = s.peek(); // Top element.          System.out.print("Top Most Element is: ");          // If t < minEle means minEle stores        // value of t.        if (t < minEle)            System.out.println(minEle);        else            System.out.println(t);    }      // Removes the top element from MyStack    void pop()    {        if (s.isEmpty())        {            System.out.println("Stack is empty");            return;        }          System.out.print("Top Most Element Removed: ");        Integer t = s.pop();          // Minimum will change as the minimum element        // of the stack is being removed.        if (t < minEle)        {            System.out.println(minEle);            minEle = 2*minEle - t;        }          else            System.out.println(t);    }      // Insert new number into MyStack    void push(Integer x)    {        if (s.isEmpty())        {            minEle = x;            s.push(x);            System.out.println("Number Inserted: " + x);            return;        }          // If new number is less than original minEle        if (x < minEle)        {            s.push(2*x - minEle);            minEle = x;        }          else            s.push(x);          System.out.println("Number Inserted: " + x);    }};  // Driver Codepublic class Main{    public static void main(String[] args)    {        MyStack s = new MyStack();        s.push(3);        s.push(5);        s.getMin();        s.push(2);        s.push(1);        s.getMin();        s.pop();        s.getMin();        s.pop();        s.peek();    }}
# Class to make a Node class Node:    # Constructor which assign argument to nade's value     def __init__(self, value):        self.value = value        self.next = None      # This method returns the string representation of the object.    def __str__(self):        return "Node({})".format(self.value)          # __repr__ is same as __str__    __repr__ = __str__    class Stack:    # Stack Constructor initialise top of stack and counter.    def __init__(self):        self.top = None        self.count = 0        self.minimum = None              # This method returns the string representation of the object (stack).    def __str__(self):        temp = self.top        out = []        while temp:            out.append(str(temp.value))            temp = temp.next        out = '\n'.join(out)        return ('Top {} \n\nStack :\n{}'.format(self.top,out))              # __repr__ is same as __str__    __repr__=__str__          # This method is used to get minimum element of stack    def getMin(self):        if self.top is None:            return "Stack is empty"        else:            print("Minimum Element in the stack is: {}" .format(self.minimum))          # Method to check if Stack is Empty or not    def isEmpty(self):        # If top equals to None then stack is empty         if self.top == None:            return True        else:        # If top not equal to None then stack is empty             return False      # This method returns length of stack         def __len__(self):        self.count = 0        tempNode = self.top        while tempNode:            tempNode = tempNode.next            self.count+=1        return self.count      # This method returns top of stack         def peek(self):        if self.top is None:            print ("Stack is empty")        else:             if self.top.value < self.minimum:                print("Top Most Element is: {}" .format(self.minimum))            else:                print("Top Most Element is: {}" .format(self.top.value))      # This method is used to add node to stack    def push(self,value):        if self.top is None:            self.top = Node(value)            self.minimum = value                  elif value < self.minimum:            temp = (2 * value) - self.minimum            new_node = Node(temp)            new_node.next = self.top            self.top = new_node            self.minimum = value        else:            new_node = Node(value)            new_node.next = self.top            self.top = new_node        print("Number Inserted: {}" .format(value))      # This method is used to pop top of stack    def pop(self):        if self.top is None:            print( "Stack is empty")        else:            removedNode = self.top.value            self.top = self.top.next            if removedNode < self.minimum:                print ("Top Most Element Removed :{} " .format(self.minimum))                self.minimum = ( ( 2 * self.minimum ) - removedNode )            else:                print ("Top Most Element Removed : {}" .format(removedNode))                                        # Driver program to test above class stack = Stack()   stack.push(3)stack.push(5) stack.getMin()stack.push(2)stack.push(1)stack.getMin()     stack.pop()stack.getMin()stack.pop() stack.peek()  # This code is contributed by Blinkii
// C# program to implement a stack // that supports getMinimum() in O(1) // time and O(1) extra space.using System;using System.Collections;  // A user defined stack that supports // getMin() in addition to Push() and Pop()public class MyStack{    public Stack s;    public int minEle;      // Constructor    public MyStack()     {        s = new Stack();    }      // Prints minimum element of MyStack    public void getMin()    {        // Get the minimum number         // in the entire stack        if (s.Count==0)            Console.WriteLine("Stack is empty");          // variable minEle stores the minimum         // element in the stack.        else            Console.WriteLine("Minimum Element in the " +                            " stack is: " + minEle);    }      // prints top element of MyStack    public void Peek()    {        if (s.Count==0)        {            Console.WriteLine("Stack is empty ");            return;        }          int t =(int)s.Peek(); // Top element.          Console.Write("Top Most Element is: ");          // If t < minEle means minEle stores        // value of t.        if (t < minEle)            Console.WriteLine(minEle);        else            Console.WriteLine(t);    }      // Removes the top element from MyStack    public void Pop()    {        if (s.Count==0)        {            Console.WriteLine("Stack is empty");            return;        }          Console.Write("Top Most Element Removed: ");        int t = (int)s.Pop();          // Minimum will change as the minimum element        // of the stack is being removed.        if (t < minEle)        {            Console.WriteLine(minEle);            minEle = 2*minEle - t;        }          else            Console.WriteLine(t);    }      // Insert new number into MyStack    public void Push(int x)    {        if (s.Count==0)        {            minEle = x;            s.Push(x);            Console.WriteLine("Number Inserted: " + x);            return;        }          // If new number is less than original minEle        if (x < minEle)        {            s.Push(2 * x - minEle);            minEle = x;        }          else            s.Push(x);          Console.WriteLine("Number Inserted: " + x);    }}  // Driver Codepublic class main{    public static void Main(String []args)    {        MyStack s = new MyStack();        s.Push(3);        s.Push(5);        s.getMin();        s.Push(2);        s.Push(1);        s.getMin();        s.Pop();        s.getMin();        s.Pop();        s.Peek();    }}  // This code is contributed by Arnab Kundu
Number Inserted: 3
Number Inserted: 5
Minimum Element in the stack is: 3
Number Inserted: 2
Number Inserted: 1
Minimum Element in the stack is: 1
Top Most Element Removed: 1
Minimum Element in the stack is: 2
Top Most Element Removed: 2
Top Most Element is: 5
Output:  
Number Inserted: 3

Number Inserted: 5

Minimum Element in the stack is: 3

Number Inserted: 2

Number Inserted: 1

Minimum Element in the stack is: 1

Top Most Element Removed: 1

Minimum Element in the stack is: 2

Top Most Element Removed: 2

Top Most Element is: 5
How does this approach work? When element to be inserted is less than minEle, we insert “2x – minEle”. The important thing to notes is, 2x – minEle will always be less than x (proved below), i.e., new minEle and while popping out this element we will see that something unusual has happened as the popped element is less than the minEle. So we will be updating minEle. 
How 2*x - minEle is less than x in push()? 
x < minEle which means x - minEle < 0

// Adding x on both sides
x - minEle + x < 0 + x 

2*x - minEle < x 

We can conclude 2*x - minEle < new minEle 
While popping out, if we find the element(y) less than the current minEle, we find the new minEle = 2*minEle – y. 
How previous minimum element, prevMinEle is, 2*minEle - y
in pop() is y the popped element?

 // We pushed y as 2x - prevMinEle. Here 
 // prevMinEle is minEle before y was inserted
 y = 2*x - prevMinEle  

 // Value of minEle was made equal to x
 minEle = x .
    
 new minEle = 2 * minEle - y 
            = 2*x - (2*x - prevMinEle)
            = prevMinEle // This is what we wanted
 
Exercise: Similar approach can be used to find the maximum element as well. Implement a stack that supports getMax() in O(1) time and constant extra space.This article is contributed by Nikhil Tekwani. If you like GeeksforGeeks and would like to contribute, you can also write an article and mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
Approach 2:
create a class node which has two variables val and min.  val will store the actual value that we are going to insert in stack ,where as min will store the min value so far seen upto that node. look into the code for better understanding.
Java
C#
/*package whatever //do not write package name here */  import java.io.*;import java.util.*;class MinStack {    Stack<Node> s;          class Node{        int val;        int min;        public Node(int val,int min){            this.val=val;            this.min=min;                      }              }      /** initialize your data structure here. */    public MinStack() {        this.s=new Stack<Node>();    }    public void push(int x) {        if(s.isEmpty()){            this.s.push(new Node(x,x));        }else{            int min=Math.min(this.s.peek().min,x);            this.s.push(new Node(x,min));        }        }       public int pop() {                  return this.s.pop().val;       }    public int top() {                      return this.s.peek().val;       }     public int getMin() {                      return this.s.peek().min;        }}    class GFG {              public static void main (String[] args) {      MinStack s=new MinStack();      s.push(-1);      s.push(10);      s.push(-4);      s.push(0);      System.out.println(s.getMin());      System.out.println(s.pop());      System.out.println(s.pop());      System.out.println(s.getMin());                    }}//time O(1);//it takes o(n) space since every node has to remember min value//this code is contributed by gireeshgudaparthi
/*package whatever //do not write package name here */using System;using System.Collections.Generic;  public class MinStack {  Stack<Node> s;    public class Node {    public int val;    public int min;      public Node(int val, int min) {      this.val = val;      this.min = min;      }    }    /** initialize your data structure here. */  public MinStack() {    this.s = new Stack<Node>();  }    public void push(int x) {    if (s.Count==0) {      this.s.Push(new Node(x, x));    } else {      int min = Math.Min(this.s.Peek().min, x);      this.s.Push(new Node(x, min));    }  }    public int pop() {      return this.s.Pop().val;  }    public int top() {      return this.s.Peek().val;  }    public int getMin() {      return this.s.Peek().min;  }}  public class GFG {    public static void Main(String[] args) {    MinStack s = new MinStack();    s.push(-1);    s.push(10);    s.push(-4);    s.push(0);    Console.WriteLine(s.getMin());    Console.WriteLine(s.pop());    Console.WriteLine(s.pop());    Console.WriteLine(s.getMin());    }}// time O(1);// it takes o(n) space since every node has to remember min value  // This code contributed by gauravrajput1 
-4
0
-4
-1
 
andrew1234
Blinkii
gireeshgudaparthi
vishalyadavvns12345
GauravRajput1
Adobe
Amazon
FactSet
Flipkart
Goldman Sachs
GreyOrange
Kuliza
Microsoft
Paytm
SAP Labs
Sapient
Snapdeal
STL
VMWare
Stack
Paytm
VMWare
Flipkart
Amazon
Microsoft
Snapdeal
FactSet
Goldman Sachs
Adobe
SAP Labs
Sapient
Kuliza
Stack
STL
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Queue using Stacks
Inorder Tree Traversal without Recursion
Program for Tower of Hanoi
Stack | Set 4 (Evaluation of Postfix Expression)
Implement a stack using singly linked list
Next Greater Element
Implement Stack using Queues
Merge Overlapping Intervals
Difference between Stack and Queue Data Structures
Iterative Depth First Traversal of Graph