Find maximum in a stack in O(1) time and O(1) extra space
Last Updated :
25 Feb, 2025
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:
Input: operations = [push(2), push(3), peek(), pop(), getMax(), push(1), getMax()]
Output: [3, 2, 2]
Explanation:
push(2): Stack is [2]
push(3): Stack is [2, 3]
peek(): Top element is 3
pop(): Removes 3, stack is [2]
getMax(): Maximum element is 2
push(1): Stack is [2, 1]
getMax(): Maximum element is 2
Input: operations = [push(10), getMax(), push(5), getMax(), pop()]
Output: [10, 5]
Explanation:
push(10): Stack is [10]
getMax(): Maximum element is 10
push(5): Stack is [10, 5]
getMax(): Maximum element is 10
pop(): Removes 5, stack is [10]
Approach:
The idea behind this approach is to use a transformation to encode the previous maximum when a new maximum is pushed onto the stack. By storing (2 * x - maxEle) for new maximums, we retain information about the old maximum in the stack.
During a pop operation, if the popped value represents a transformed maximum, we can restore the previous maximum using the formula maxEle = 2 * maxEle - y.
Push Operation
- When the stack is empty, we insert the given element x into the stack and set maxEle (the variable storing the current maximum element) to x.
- Otherwise, we compare the new element x with maxEle. If x ≤ maxEle, simply insert x into the stack. The maximum element remains unchanged. If x > maxEle, the stack does not store x directly. Instead, it stores a modified value calculated as (2 * x - maxEle). Then, maxEle is updated to x.
Pop Operation
Remove the top element of the stack and check its relationship with maxEle:
- If the top element y ≤ maxEle, simply remove it. The maximum element remains unchanged.
- If y > maxEle, it indicates that y was a placeholder value (not an actual element in the stack). To retrieve the previous maximum, update maxEle using the formula (2 * maxEle - y). This operation restores the value of the previous maximum.
Why the Equations Work?
The equations maintain the relationship between the stack's maximum element and the actual stack contents.
- When pushing an element, if it’s greater than maxEle, the modified value (2 * x - maxEle) is stored. This value is always greater than the previous maxEle.
- When popping a placeholder value, the previous maximum is recalculated as (2 * maxEle - y).
This ensures that the stack doesn’t store the actual maximum value when x exceeds maxEle, and the maximum value is always tracked using maxEle.
Push Operations:
- Push 3: Stack = [3], maxEle = 3.
- Push 5: Since 5 > maxEle, store 7 (2*5 - 3) in the stack and update maxEle to 5. Stack = [3, 7].
- Push 2: Since 2 ≤ maxEle, insert 2 into the stack. Stack = [3, 7, 2]. maxEle = 5.
- Push 1: Since 1 ≤ maxEle, insert 1 into the stack. Stack = [3, 7, 2, 1]. maxEle = 5.
Pop Operations:
- Pop 1: Since 1 ≤ maxEle, remove 1. Stack = [3, 7, 2]. maxEle = 5.
- Pop 2: Since 2 ≤ maxEle, remove 2. Stack = [3, 7]. maxEle = 5.
- Pop 7: Since 7 > maxEle, retrieve original maxEle (5) and update maxEle to 2*5 - 7 = 3. Stack = [3]. maxEle = 3.
Below is the implementation of the above approach:
C++
// C++ program to implement a stack that find
// maximum in stack in O(1) time and space.
#include <iostream>
#include <stack>
using namespace std;
// Class to implement a stack with getMax()
class MaxStack {
private:
stack<int> s;
int maxEle;
public:
MaxStack() {
maxEle = -1;
}
// Add an element to the top of Stack
void push(int x) {
if (s.empty()) {
maxEle = x;
s.push(x);
}
// If new number is greater than maxEle
else if (x > maxEle) {
s.push(2 * x - maxEle);
maxEle = x;
} else {
s.push(x);
}
}
// Remove the top element from the Stack
void pop() {
if (s.empty()) {
return;
}
int top = s.top();
s.pop();
// Maximum will change if the maximum element
// of the stack is being removed.
if (top > maxEle) {
maxEle = 2 * maxEle - top;
}
}
// Returns top element of the Stack
int peek() {
if (s.empty()) {
return -1;
}
int top = s.top();
// If maxEle < top means maxEle stores value of top.
return (maxEle < top) ? maxEle : top;
}
// Finds maximum element of Stack
int getMax() {
if (s.empty())
return -1;
// variable maxEle stores the maximum element
// in the stack
return maxEle;
}
};
int main() {
MaxStack stk;
stk.push(2);
stk.push(3);
cout << stk.peek() << " ";
stk.pop();
cout << stk.getMax() << " ";
stk.push(1);
cout << stk.getMax() << " ";
return 0;
}
Java
// Java program to implement a stack that find
// maximum in stack in O(1) time and space.
import java.util.Stack;
// Class to implement a stack with getMax()
class MaxStack {
private Stack<Integer> s;
private int maxEle;
public MaxStack() {
s = new Stack<>();
maxEle = -1;
}
// Add an element to the top of Stack
public void push(int x) {
if (s.isEmpty()) {
maxEle = x;
s.push(x);
}
// If new number is greater than maxEle
else if (x > maxEle) {
s.push(2 * x - maxEle);
maxEle = x;
} else {
s.push(x);
}
}
// Remove the top element from the Stack
public void pop() {
if (s.isEmpty()) {
return;
}
int top = s.pop();
// Maximum will change if the maximum element
// of the stack is being removed.
if (top > maxEle) {
maxEle = 2 * maxEle - top;
}
}
// Returns top element of the Stack
public int peek() {
if (s.isEmpty()) {
return -1;
}
int top = s.peek();
// If maxEle < top means maxEle stores value of top.
return (maxEle < top) ? maxEle : top;
}
// Finds maximum element of Stack
public int getMax() {
if (s.isEmpty()) {
return -1;
}
// variable maxEle stores the maximum element
// in the stack
return maxEle;
}
public static void main(String[] args) {
MaxStack stk = new MaxStack();
stk.push(2);
stk.push(3);
System.out.print(stk.peek() + " ");
stk.pop();
System.out.print(stk.getMax() + " ");
stk.push(1);
System.out.print(stk.getMax() + " ");
}
}
Python
# Python program to implement a stack that finds
# maximum in stack in O(1) time and space.
# Class to implement a stack with getMax()
class MaxStack:
def __init__(self):
self.s = []
self.maxEle = -1
# Add an element to the top of Stack
def push(self, x):
if not self.s:
self.maxEle = x
self.s.append(x)
# If new number is greater than maxEle
elif x > self.maxEle:
self.s.append(2 * x - self.maxEle)
self.maxEle = x
else:
self.s.append(x)
# Remove the top element from the Stack
def pop(self):
if not self.s:
return
top = self.s.pop()
# Maximum will change if the maximum element
# of the stack is being removed.
if top > self.maxEle:
self.maxEle = 2 * self.maxEle - top
# Returns top element of the Stack
def peek(self):
if not self.s:
return -1
top = self.s[-1]
# If maxEle < top means maxEle stores value of top.
return self.maxEle if self.maxEle < top else top
# Finds maximum element of Stack
def getMax(self):
if not self.s:
return -1
# variable maxEle stores the maximum element
# in the stack
return self.maxEle
if __name__ == "__main__":
stk = MaxStack()
stk.push(2)
stk.push(3)
print(stk.peek(), end=" ")
stk.pop()
print(stk.getMax(), end=" ")
stk.push(1)
print(stk.getMax(), end=" ")
C#
// C# program to implement a stack that find
// maximum in stack in O(1) time and space.
using System;
using System.Collections.Generic;
// Class to implement a stack with getMax()
class MaxStack {
private Stack<int> s;
private int maxEle;
public MaxStack() {
s = new Stack<int>();
maxEle = -1;
}
// Add an element to the top of Stack
public void Push(int x) {
if (s.Count == 0) {
maxEle = x;
s.Push(x);
}
// If new number is greater than maxEle
else if (x > maxEle) {
s.Push(2 * x - maxEle);
maxEle = x;
} else {
s.Push(x);
}
}
// Remove the top element from the Stack
public void Pop() {
if (s.Count == 0) {
return;
}
int top = s.Pop();
// Maximum will change if the maximum element
// of the stack is being removed.
if (top > maxEle) {
maxEle = 2 * maxEle - top;
}
}
// Returns top element of the Stack
public int Peek() {
if (s.Count == 0) {
return -1;
}
int top = s.Peek();
// If maxEle < top means maxEle stores value of top.
return (maxEle < top) ? maxEle : top;
}
// Finds maximum element of Stack
public int GetMax() {
if (s.Count == 0) {
return -1;
}
// variable maxEle stores the maximum element
// in the stack
return maxEle;
}
public static void Main() {
MaxStack stk = new MaxStack();
stk.Push(2);
stk.Push(3);
Console.Write(stk.Peek() + " ");
stk.Pop();
Console.Write(stk.GetMax() + " ");
stk.Push(1);
Console.Write(stk.GetMax() + " ");
}
}
JavaScript
// JavaScript program to implement a stack that finds
// maximum in stack in O(1) time and space.
// Class to implement a stack with getMax()
class MaxStack {
constructor() {
this.s = [];
this.maxEle = -1;
}
// Add an element to the top of Stack
push(x) {
if (this.s.length === 0) {
this.maxEle = x;
this.s.push(x);
}
// If new number is greater than maxEle
else if (x > this.maxEle) {
this.s.push(2 * x - this.maxEle);
this.maxEle = x;
} else {
this.s.push(x);
}
}
// Remove the top element from the Stack
pop() {
if (this.s.length === 0) {
return;
}
let top = this.s.pop();
// Maximum will change if the maximum element
// of the stack is being removed.
if (top > this.maxEle) {
this.maxEle = 2 * this.maxEle - top;
}
}
// Returns top element of the Stack
peek() {
if (this.s.length === 0) {
return -1;
}
let top = this.s[this.s.length - 1];
// If maxEle < top means maxEle stores value of top.
return this.maxEle < top ? this.maxEle : top;
}
// Finds maximum element of Stack
getMax() {
if (this.s.length === 0) {
return -1;
}
// variable maxEle stores the maximum element
// in the stack
return this.maxEle;
}
}
// Driver Code
const stk = new MaxStack();
stk.push(2);
stk.push(3);
console.log(stk.peek(), " ");
stk.pop();
console.log(stk.getMax(), " ");
stk.push(1);
console.log(stk.getMax(), " ");
How does this approach work?
When the element to be inserted is more than maxEle, we insert “2x – maxEle”. The important thing to note is, that 2x – maxEle will always be more than x (proved below), i.e., new maxEle and while popping out this element we will see that something unusual has happened as the popped element is less than the maxEle. So we will be updating maxEle.
How 2*x – maxEle is more than x in push()?
x > maxEle which means x – maxEle > 0
// Adding x on both sides
x – maxEle + x > 0 + x
2*x – maxEle > x
We can conclude 2*x – maxEle > new maxEle
While popping out, if we find the element(y) more than the current maxEle, we find the new maxEle = 2*maxEle – y
How previous max element, prevMaxEle is, 2*maxEle – y
in pop() is y the popped element?
// We pushed y as 2x – prevMaxEle. Here
// prevMaxEle is maxEle before y was inserted
y = 2*x – prevMaxEle
// Value of maxEle was made equal to x
maxEle = x
new maxEle = 2 * maxEle – y
= 2*x – (2*x – prevMaxEle)
= prevMaxEle // This is what we wanted
Time Complexity: O(1), as all these operations are constant-time due to direct stack manipulation and comparisons.
Auxiliary Space: O(1), as we use only a fixed amount of extra space (for maxEle
).
Similar Reads
Find duplicates in O(n) time and O(n) extra space
Given an array arr[] of n elements that contains elements from 0 to n-1, with any of these numbers appearing any number of times. The task is to find the repeating numbers.Note: The repeating element should be printed only once.Example: Input: n = 7, arr[] = [1, 2, 3, 6, 3, 6, 1]Output: 1, 3, 6Expla
10 min read
Find maximum in stack in O(1) without using additional stack in Python
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 in Python. Examples: Input: Consider the following SpecialStack 16 â> TOP29151918When getMax() is called it should return 29, which is the maximum element in the current stack
3 min read
Find duplicate in an array in O(n) and by using O(1) extra space
Given an array arr[] containing n integers where each integer is between 1 and (n-1) (inclusive). There is only one duplicate element, find the duplicate element in O(n) time complexity and O(1) space.Examples : Input : arr[] = {1, 4, 3, 4, 2} Output : 4Input : arr[] = {1, 3, 2, 1}Output : 1Approach
13 min read
Duplicates in an array in O(n) time and by using O(1) extra space | Set-3
Given an array of n elements which contains elements from 0 to n-1, with any of these numbers appearing any number of times. Find these repeating numbers in O(n) and using only constant memory space. It is required that the order in which elements repeat should be maintained. If there is no repeatin
10 min read
Design a dynamic stack using arrays that supports getMin() in O(1) time and O(1) extra space
Design a special dynamic Stack using an array that supports all the stack operations such as push(), pop(), peek(), isEmpty(), and getMin() operations in constant Time and Space complexities. Examples: Assuming the right to left orientation as the top to bottom orientation and performing the operati
15+ min read
Find index of an extra element present in one sorted array
Given two sorted arrays. There is only 1 difference between the arrays. The first array has one element extra added in between. Find the index of the extra element. Examples: Input: {2, 4, 6, 8, 9, 10, 12}; {2, 4, 6, 8, 10, 12}; Output: 4 Explanation: The first array has an extra element 9. The extr
15+ min read
Time and Space Complexity analysis of Stack operations
What is Stack?Stack is a linear data structure that follows a particular order in which the elements are inserted and deleted. A stack follows the principle of last in first out(LIFO) which means that the last element inserted into the stack should be removed first. Consider an example of plates sta
15+ min read
Design a stack to retrieve original elements and return the minimum element in O(1) time and O(1) space
Our task is to 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 performed with time complexi
15+ min read
Find duplicates in constant array with elements 0 to N-1 in O(1) space
Given a constant array of n elements which contains elements from 1 to n-1, with any of these numbers appearing any number of times. Find any one of these repeating numbers in O(n) and using only constant memory space. Examples: Input : arr[] = {1, 2, 3, 4, 5, 6, 3} Output : 3 As the given array is
12 min read
Design a stack that supports getMin() in O(1) time
Design a Data Structure SpecialStack that supports all the stack operations like push(), pop(), peek() and an additional operation getMin() which should return minimum element from the SpecialStack. All these operations of SpecialStack must have a time complexity of O(1). Example: Input: queries = [
15+ min read