Find maximum in stack in O(1) without using additional stack

07 Jun, 2022
The task is to design a stack which can get the maximum value in the stack in O(1) time without using an additional stack.
Examples: 
Input: push(2) findMax() push(6) findMax() pop() findMax() Output: 2 inserted in stack Maximum value in the stack: 2 6 inserted in stack Maximum value in the stack: 6 Element popped Maximum value in the stack: 2 
Approach: Instead of pushing a single element to the stack, push a pair instead. The pair consists of the (value, localMax) where localMax is the maximum value upto that element.  
When we insert a new element, if the new element is greater than the local maximum below it, we set the local maximum of a new element equal to the element itself.
Else, we set the local maximum of the new element equal to the local maximum of the element below it.
The local maximum of the top of the stack will be the overall maximum.
Now if we want to know the maximum at any given point, we ask the top of the stack for local maximum associated with it which can be done in O(1).
Below is the implementation of the above approach:  
C++
Java
Python3
C#
Javascript
// C++ implementation of the approach#include <iostream>using namespace std; struct Block {     // A block has two elements    // as components    int value, localMax;}; class Stack { private:    // Pointer of type block,    // Will be useful later as the    // size can be dynamically allocated    struct Block* S;    int size, top; public:    Stack(int);    void push(int);    void pop();    void max();}; Stack::Stack(int n){     // Setting size of stack and    // initial value of top    size = n;    S = new Block[n];    top = -1;} // Function to push an element to the stackvoid Stack::push(int n){     // Doesn't allow pushing elements    // if stack is full    if (top == size - 1) {        cout << "Stack is full" << endl;    }    else {        top++;         // If the inserted element is the first element        // then it is the maximum element, since no other        // elements is in the stack, so the localMax        // of the first element is the element itself        if (top == 0) {            S[top].value = n;            S[top].localMax = n;        }        else {             // If the newly pushed element is            // less than the localMax of element below it,            // Then the over all maximum doesn't change            // and hence, the localMax of the newly inserted            // element is same as element below it            if (S[top - 1].localMax > n) {                S[top].value = n;                S[top].localMax = S[top - 1].localMax;            }             // Newly inserted element is greater than the localMax            // below it, hence the localMax of new element            // is the element itself            else {                S[top].value = n;                S[top].localMax = n;            }        }         cout << n << " inserted in stack" << endl;    }} // Function to remove an element// from the top of the stackvoid Stack::pop(){     // If stack is empty    if (top == -1) {        cout << "Stack is empty" << endl;    }     // Remove the element if the stack    // is not empty    else {        top--;        cout << "Element popped" << endl;    }} // Function to find the maximum// element from the stackvoid Stack::max(){     // If stack is empty    if (top == -1) {        cout << "Stack is empty" << endl;    }    else {         // The overall maximum is the local maximum        // of the top element        cout << "Maximum value in the stack: "             << S[top].localMax << endl;    }} // Driver codeint main(){     // Create stack of size 5    Stack S1(5);     S1.push(2);    S1.max();    S1.push(6);    S1.max();    S1.pop();    S1.max();     return 0;}
// Java implementation of the approachclass GFG{     static class Block{     // A block has two elements    // as components    int value, localMax;}; static class Stack{     // Pointer of type block,    // Will be useful later as the    // size can be dynamically allocated    Block S[];    int size, top;  Stack(int n){     // Setting size of stack and    // initial value of top    size = n;    S = new Block[n];    for(int i=0;i<n;i++)S[i]=new Block();    top = -1;} // Function to push an element to the stackvoid push(int n){     // Doesn't allow pushing elements    // if stack is full    if (top == size - 1)    {        System.out.print( "Stack is full" );    }    else    {        top++;         // If the inserted element is the first element        // then it is the maximum element, since no other        // elements is in the stack, so the localMax        // of the first element is the element itself        if (top == 0)        {            S[top].value = n;            S[top].localMax = n;        }        else        {             // If the newly pushed element is            // less than the localMax of element below it,            // Then the over all maximum doesn't change            // and hence, the localMax of the newly inserted            // element is same as element below it            if (S[top - 1].localMax > n)            {                S[top].value = n;                S[top].localMax = S[top - 1].localMax;            }             // Newly inserted element is greater than the localMax            // below it, hence the localMax of new element            // is the element itself            else            {                S[top].value = n;                S[top].localMax = n;            }        }         System.out.println( n + " inserted in stack" );    }} // Function to remove an element// from the top of the stackvoid pop(){     // If stack is empty    if (top == -1)    {        System.out.println( "Stack is empty");    }     // Remove the element if the stack    // is not empty    else    {        top--;        System.out.println( "Element popped" );    }} // Function to find the maximum// element from the stackvoid max(){     // If stack is empty    if (top == -1)    {        System.out.println( "Stack is empty");    }    else    {         // The overall maximum is the local maximum        // of the top element        System.out.println( "Maximum value in the stack: "+                                            S[top].localMax);    }}} // Driver codepublic static void main(String args[]){     // Create stack of size 5    Stack S1=new Stack(5);     S1.push(2);    S1.max();    S1.push(6);    S1.max();    S1.pop();    S1.max();}} // This code is contributed by Arnab Kundu
# Python3 implementation of the approachclass Block:         # A block has two elements    # as components  (i.e. value and localMax)    def __init__(self, value, localMax):        self.value = value        self.localMax = localMax class Stack:    def __init__(self, size):                 # Setting size of stack and        # initial value of top        self.stack = [None] * size        self.size = size        self.top = -1     # Function to push an element    # to the stack    def push(self, value):         # Don't allow pushing elements        # if stack is full        if self.top == self.size - 1:            print("Stack is full")        else:            self.top += 1                         # If the inserted element is the first element            # then it is the maximum element, since no other            # elements is in the stack, so the localMax            # of the first element is the element itself            if self.top == 0:                self.stack[self.top] = Block(value, value)             else:                                 # If the newly pushed element is less                # than the localMax of element below it,                # Then the over all maximum doesn't change                # and hence, the localMax of the newly inserted                # element is same as element below it                if self.stack[self.top - 1].localMax > value:                    self.stack[self.top] = Block(                        value, self.stack[self.top - 1].localMax)                 # Newly inserted element is greater than                # the localMax below it, hence the localMax                # of new element is the element itself                else:                    self.stack                    self.stack[self.top] = Block(value, value)                                 print(value, "inserted in the stack")                 # Function to remove an element     # from the top of the stack             def pop(self):                 # If stack is empty        if self.top == -1:            print("Stack is empty")         # Remove the element if the stack        # is not empty        else:            self.top -= 1            print("Element popped")                 # Function to find the maximum     # element from the stack     def max(self):                 # If stack is empty        if self.top == -1:            print("Stack is empty")        else:                         # The overall maximum is the local maximum            # of the top element            print("Maximum value in the stack:",                  self.stack[self.top].localMax) # Driver code # Create stack of size 5stack = Stack(5)stack.push(2)stack.max()stack.push(6)stack.max()stack.pop()stack.max() # This code is contributed by girishthatte
// C# implementation of the approachusing System; class GFG{     public class Block{     // A block has two elements    // as components    public int value, localMax;}; public class Stack{     // Pointer of type block,    // Will be useful later as the    // size can be dynamically allocated    public Block []S;    public int size, top;  public Stack(int n){     // Setting size of stack and    // initial value of top    size = n;    S = new Block[n];    for(int i = 0; i < n; i++)S[i] = new Block();    top = -1;} // Function to push an element to the stackpublic void push(int n){     // Doesn't allow pushing elements    // if stack is full    if (top == size - 1)    {        Console.Write( "Stack is full" );    }    else    {        top++;         // If the inserted element is the first element        // then it is the maximum element, since no other        // elements is in the stack, so the localMax        // of the first element is the element itself        if (top == 0)        {            S[top].value = n;            S[top].localMax = n;        }        else        {             // If the newly pushed element is            // less than the localMax of element below it,            // Then the over all maximum doesn't change            // and hence, the localMax of the newly inserted            // element is same as element below it            if (S[top - 1].localMax > n)            {                S[top].value = n;                S[top].localMax = S[top - 1].localMax;            }             // Newly inserted element is greater than the localMax            // below it, hence the localMax of new element            // is the element itself            else            {                S[top].value = n;                S[top].localMax = n;            }        }         Console.WriteLine( n + " inserted in stack" );    }} // Function to remove an element// from the top of the stackpublic void pop(){     // If stack is empty    if (top == -1)    {        Console.WriteLine( "Stack is empty");    }     // Remove the element if the stack    // is not empty    else    {        top--;        Console.WriteLine( "Element popped" );    }} // Function to find the maximum// element from the stackpublic void max(){     // If stack is empty    if (top == -1)    {        Console.WriteLine( "Stack is empty");    }    else    {         // The overall maximum is the local maximum        // of the top element        Console.WriteLine( "Maximum value in the stack: "+                                            S[top].localMax);    }}} // Driver codepublic static void Main(String []args){     // Create stack of size 5    Stack S1 = new Stack(5);     S1.push(2);    S1.max();    S1.push(6);    S1.max();    S1.pop();    S1.max();}} // This code contributed by Rajput-Ji
<script> /// JavaScript implementation of the approachclass Block{     /// A block has two elements    /// as components (i.e. value and localMax)    constructor(value, localMax){        this.value = value        this.localMax = localMax    }} class Stack{    constructor(size){                 /// Setting size of stack and        /// initial value of top        this.stack = new Array(size).fill(null)        this.size = size        this.top = -1    }     // Function to push an element    // to the stack    push(value){         // Don't allow pushing elements        // if stack is full        if(this.top == this.size - 1)            document.write("Stack is full","</br>")        else{            this.top += 1                         // If the inserted element is the first element            // then it is the maximum element, since no other            // elements is in the stack, so the localMax            // of the first element is the element itthis            if(this.top == 0)                this.stack[this.top] = new Block(value, value)             else{                                 // If the newly pushed element is less                // than the localMax of element below it,                // Then the over all maximum doesn't change                // and hence, the localMax of the newly inserted                // element is same as element below it                if(this.stack[this.top - 1].localMax > value){                    this.stack[this.top] = new Block(                        value, this.stack[this.top - 1].localMax)                    }                 // Newly inserted element is greater than                // the localMax below it, hence the localMax                // of new element is the element itthis                else{                    this.stack[this.top] = new Block(value, value)                }            }                                 document.write(value, "inserted in the stack","</br>")        }    }                 // Function to remove an element    // from the top of the stack           pop(){                 // If stack is empty        if(this.top == -1)            document.write("Stack is empty","</br>")         // Remove the element if the stack        // is not empty        else{            this.top -= 1            document.write("Element popped","</br>")        }    }                 // Function to find the maximum    // element from the stack    max(){                 // If stack is empty        if(this.top == -1)            document.write("Stack is empty","</br>")        else{                         // The overall maximum is the local maximum            // of the top element            document.write("Maximum value in the stack:",this.stack[this.top].localMax,"</br>")        }    }} // Driver code // Create stack of size 5let stack = new Stack(5)stack.push(2)stack.max()stack.push(6)stack.max()stack.pop()stack.max() /// This code is contributed by shinjanpatra </script>
2 inserted in stack
Maximum value in the stack: 2
6 inserted in stack
Maximum value in the stack: 6
Element popped
Maximum value in the stack: 2
 
Time Complexity : O(1)
Auxiliary Space: O(1) 
andrew1234
Rajput-Ji
Akanksha_Rai
girishthatte
pankajsharmagfg
shinjanpatra
Data Structures
Stack
Data Structures
Stack
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Introduction to Data Structures
What is Hashing | A Complete Tutorial
What is Data Structure: Types, Classifications and Applications
Find if there is a path between two vertices in an undirected graph
TCS NQT Coding Sheet
Stack Data Structure (Introduction and Program)
Stack in Python
Stack Class in Java
Check for Balanced Brackets in an expression (well-formedness) using Stack
Introduction to Data Structures