Given a stack of integers. The task is to design a special stack such that the maximum element can be found in O(1) time and O(1) extra space.
Examples:
Given Stack :
2
5
1
64 --> Maximum
So Output must be 64 when getMax() is called.
Below are the different functions designed to push and pop elements from the stack.
Push(x) : Inserts x at the top of stack.
- If stack is empty, insert x into the stack and make maxEle equal to x.
- If stack is not empty, compare x with maxEle. Two cases arise:
- If x is less than or equal to maxEle, simply insert x.
- If x is greater than maxEle, insert (2*x – maxEle) into the stack and make maxEle equal to x. For example, let previous maxEle was 3. Now we want to insert 4. We update maxEle as 4 and insert 2*4 – 3 = 5 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 less than or equal to maxEle, the maximum element in the stack is still maxEle.
- If y is greater than maxEle, the maximum element now becomes (2*maxEle – y), so update (maxEle = 2*maxEle – y). This is where we retrieve previous maximum from current maximum and its value in stack. For example, let the element to be removed be 5 and maxEle be 4. We remove 5 and update maxEle as 2*4 – 5 = 3.]
How does the Above Equation work?
While pushing x into stack if x is greater than maxEle we push modified value = 2 * x-maxEle.
So, x > val
=> x-val>0
=> adding x to both sides 2x – val >x (this is our updated maxEle from next steps).
Means the modified value is greater than maxEle.
After popped out the maxEle should be updated
so maxEle = 2*maxEle – y (top value)
= 2*maxEle – (2*x- previousMax)
= 2*maxEle – 2*maxEle (maxELe = x in next steps) + previousMax
= previousMax.
Important Points:
- Stack doesn’t hold actual value of an element if it is maximum so far.
- Actual maximum element is always stored in maxEle
Illustration:
Push(x):
- Number to be Inserted: 3, Stack is empty, so insert 3 into stack, and maxEle = 3.
- Number to be Inserted: 5, Stack is not empty, 5> maxEle, insert (2*5-3) into stack and maxEle = 5.
- Number to be Inserted: 2, Stack is not empty, 2< maxEle, insert 2 into stack and maxEle = 5.
- Number to be Inserted: 1, Stack is not empty, 1< maxEle, insert 1 into stack and maxEle = 5.
Pop() :
- Initially the maximum element maxEle in the stack is 5.
- Number removed: 1, Since 1 is less than maxEle just pop 1. maxEle=5.
- Number removed: 2, 2<maxEle, so number removed is 2 and maxEle is still equal to 5.
- Number removed: 7, 7> maxEle, original number is maxEle which is 5 and new maxEle = 2*5 – 7 = 3.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
struct MyStack {
stack< int > s;
int maxEle;
void getMax()
{
if (s.empty())
cout << "Stack is empty\n" ;
else
cout << "Maximum Element in the stack is: "
<< maxEle << "\n" ;
}
void peek()
{
if (s.empty()) {
cout << "Stack is empty " ;
return ;
}
int t = s.top();
cout << "Top Most Element is: " ;
(t > maxEle) ? cout << maxEle : cout << t;
}
void pop()
{
if (s.empty()) {
cout << "Stack is empty\n" ;
return ;
}
cout << "Top Most Element Removed: " ;
int t = s.top();
s.pop();
if (t > maxEle) {
cout << maxEle << "\n" ;
maxEle = 2 * maxEle - t;
}
else
cout << t << "\n" ;
}
void push( int x)
{
if (s.empty()) {
maxEle = x;
s.push(x);
cout << "Number Inserted: " << x << "\n" ;
return ;
}
if (x > maxEle) {
s.push(2 * x - maxEle);
maxEle = x;
}
else
s.push(x);
cout << "Number Inserted: " << x << "\n" ;
}
};
int main()
{
MyStack s;
s.push(3);
s.push(5);
s.getMax();
s.push(7);
s.push(19);
s.getMax();
s.pop();
s.getMax();
s.pop();
s.peek();
return 0;
}
|
Java
import java.util.*;
class GFG
{
static class MyStack
{
Stack<Integer> s = new Stack<Integer>();
int maxEle;
void getMax()
{
if (s.empty())
System.out.print( "Stack is empty\n" );
else
System.out.print( "Maximum Element in" +
"the stack is: " +maxEle + "\n" );
}
void peek()
{
if (s.empty())
{
System.out.print( "Stack is empty " );
return ;
}
int t = s.peek();
System.out.print( "Top Most Element is: " );
if (t > maxEle)
System.out.print(maxEle);
else
System.out.print(t);
}
void pop()
{
if (s.empty())
{
System.out.print( "Stack is empty\n" );
return ;
}
System.out.print( "Top Most Element Removed: " );
int t = s.peek();
s.pop();
if (t > maxEle)
{
System.out.print(maxEle + "\n" );
maxEle = 2 * maxEle - t;
}
else
System.out.print(t + "\n" );
}
void push( int x)
{
if (s.empty())
{
maxEle = x;
s.push(x);
System.out.print( "Number Inserted: " + x + "\n" );
return ;
}
if (x > maxEle)
{
s.push( 2 * x - maxEle);
maxEle = x;
}
else
s.push(x);
System.out.print( "Number Inserted: " + x + "\n" );
}
};
public static void main(String[] args)
{
MyStack s = new MyStack();
s.push( 3 );
s.push( 5 );
s.getMax();
s.push( 7 );
s.push( 19 );
s.getMax();
s.pop();
s.getMax();
s.pop();
s.peek();
}
}
|
Python 3
class Node:
def __init__( self , value):
self .value = value
self . next = None
def __str__( self ):
return "Node({})" . format ( self .value)
__repr__ = __str__
class Stack:
def __init__( self ):
self .top = None
self .count = 0
self .maximum = None
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__ = __str__
def getMax( self ):
if self .top is None :
return "Stack is empty"
else :
print ( "Maximum Element in the stack is: {}" . format ( self .maximum))
def isEmpty( self ):
if self .top = = None :
return True
else :
return False
def __len__( self ):
self .count = 0
tempNode = self .top
while tempNode:
tempNode = tempNode. next
self .count + = 1
return self .count
def peek( self ):
if self .top is None :
print ( "Stack is empty" )
else :
if self .top.value > self .maximum:
print ( "Top Most Element is: {}" . format ( self .maximum))
else :
print ( "Top Most Element is: {}" . format ( self .top.value))
def push( self ,value):
if self .top is None :
self .top = Node(value)
self .maximum = value
elif value > self .maximum :
temp = ( 2 * value) - self .maximum
new_node = Node(temp)
new_node. next = self .top
self .top = new_node
self .maximum = value
else :
new_node = Node(value)
new_node. next = self .top
self .top = new_node
print ( "Number Inserted: {}" . format (value))
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 .maximum:
print ( "Top Most Element Removed :{} " . format ( self .maximum))
self .maximum = ( ( 2 * self .maximum ) - removedNode )
else :
print ( "Top Most Element Removed : {}" . format (removedNode))
stack = Stack()
stack.push( 3 )
stack.push( 5 )
stack.getMax()
stack.push( 7 )
stack.push( 19 )
stack.getMax()
stack.pop()
stack.getMax()
stack.pop()
stack.peek()
|
C#
using System;
using System.Collections.Generic;
class GFG
{
public class MyStack
{
public Stack< int > s = new Stack< int >();
public int maxEle;
public void getMax()
{
if (s.Count == 0)
Console.Write( "Stack is empty\n" );
else
Console.Write( "Maximum Element in" +
"the stack is: " +maxEle + "\n" );
}
public void peek()
{
if (s.Count == 0)
{
Console.Write( "Stack is empty " );
return ;
}
int t = s.Peek();
Console.Write( "Top Most Element is: " );
if (t > maxEle)
Console.Write(maxEle);
else
Console.Write(t);
}
public void pop()
{
if (s.Count == 0)
{
Console.Write( "Stack is empty\n" );
return ;
}
Console.Write( "Top Most Element Removed: " );
int t = s.Peek();
s.Pop();
if (t > maxEle)
{
Console.Write(maxEle + "\n" );
maxEle = 2 * maxEle - t;
}
else
Console.Write(t + "\n" );
}
public void push( int x)
{
if (s.Count == 0)
{
maxEle = x;
s.Push(x);
Console.Write( "Number Inserted: " + x + "\n" );
return ;
}
if (x > maxEle)
{
s.Push(2 * x - maxEle);
maxEle = x;
}
else
s.Push(x);
Console.Write( "Number Inserted: " + x + "\n" );
}
};
public static void Main(String[] args)
{
MyStack s = new MyStack();
s.push(3);
s.push(5);
s.getMax();
s.push(7);
s.push(19);
s.getMax();
s.pop();
s.getMax();
s.pop();
s.peek();
}
}
|
Javascript
<script>
let s = [];
let maxEle;
function getMax()
{
if (s.length == 0)
document.write( "Stack is empty" + "</br>" );
else
document.write( "Maximum Element in " +
"the stack is: " +maxEle + "</br>" );
}
function peek()
{
if (s.length == 0)
{
document.write( "Stack is empty " );
return ;
}
let t = s[s.length - 1];
document.write( "Top Most Element is: " );
if (t > maxEle)
document.write(maxEle);
else
document.write(t);
}
function pop()
{
if (s.length == 0)
{
document.write( "Stack is empty" + "</br>" );
return ;
}
document.write( "Top Most Element Removed: " );
let t = s[s.length - 1];
s.pop();
if (t > maxEle)
{
document.write(maxEle + "</br>" );
maxEle = 2 * maxEle - t;
}
else
document.write(t + "</br>" );
}
function push(x)
{
if (s.length == 0)
{
maxEle = x;
s.push(x);
document.write( "Number Inserted: " + x + "</br>" );
return ;
}
if (x > maxEle)
{
s.push(2 * x - maxEle);
maxEle = x;
}
else
s.push(x);
document.write( "Number Inserted: " + x + "</br>" );
}
push(3);
push(5);
getMax();
push(7);
push(19);
getMax();
pop();
getMax();
pop();
peek();
</script>
|
OutputNumber Inserted: 3
Number Inserted: 5
Maximum Element in the stack is: 5
Number Inserted: 7
Number Inserted: 19
Maximum Element in the stack is: 19
Top Most Element Removed: 19
Maximum Element in the stack is: 7
Top Most Element Removed: 7
Top Most Element is: 5
Complexity Analysis:
- Time Complexity: O(1)
- Auxiliary Space: O(1)