AfterAcademy Tech
•
01 May 2020

Difficulty: Easy
Asked in: Amazon, Microsoft, Yahoo, Adobe
Given Problem is to design a special stack data structure such that it supports following operations in constant O(1) time complexity.
For Example:
Input:
stck = minStack() //Create an object of your special stack
stck.push(2)
stck.push(4)
stck.top() ----------> returns 4 as 4 is at the top(last inserted element)
stck.getMin() -------> returns 2 as it is the current minimum
stck.pop()
stck.push(-1)
stck.getMin() -------> returns -1 as now it is the minimum element.
Possible questions to ask the interviewer: →
You can try solving this problem here and then move on to the solution part.
So here we are going to discuss two possible solutions to solve this problem. Both the solutions will be of constant time complexity. However, the second solution will be more optimised in terms of space and will be testing your mathematical skills. Excited? Let’s see both the solutions in details.
This approach will use an array which will be used to store elements at every point whenever its value is less than the top element of the stack. So we will keep checking every time before pushing the element into the stack(push() operation) if its value is smaller than the last element inserted into the array or not. If yes, we will add this element to the array as well as to the stack. Else, we will only add the element to the stack.
In case of the pop() operation, we will check if the element to be deleted(top element) is the same as the last element inserted to the array. If this is the case, we have to delete this element from both the places(stack and array) so that the last element of the array now will point to the current minimum element.
The top() operation will simply return the last element present in the stack and the getMin() operation will return the last element of the array.
Solution steps
Pseudo-code
class MinStack {
public:
vector <int> stack
vector <int> minArray
MinStack() {
//Constructor
}
//Push operation
void push(int elem) {
if(!minArray.empty())
{
if(elem <= minArray.back())
minArray.push_back(elem)
}
else
minArray.push_back(elem)
stack.push_back(elem)
}
//Pop operation
void pop() {
if(stack.back() == minArray.back())
{
minArray.pop_back()
}
stack.pop_back()
}
//Top operation
int top() {
if(!stack.empty()) //Simply returns top element from stack
return stack.back()
else
return -1
}
//getMin operation
int getMin() {
if(!minArray.empty()) //Simply returns last element from //minArray
return minArray.back()
else
return -1
}
}
Note: Vectors are dynamic arrays supported by C++ STL. push_back(T elem) will push an element to vector, pop_back() will delete the last element, empty() will check if the vector is empty or not and back() will give the last element of the vector. For getting more idea: — Go here. You can find its subtitute in whaever language you code.
Complexity Analysis
Time Complexity: O(1)
Space Complexity: O(N)
Critical ideas to think!
In this approach instead of using an array and increasing the space complexity, we will rather use a variable minElement which will store the current minimum element of the stack at every point.
Have you thought about the above given critical idea? Hmm, the problem is when we have to pop this minElement from the stack. How will we update the minElem then?
To solve this issue, we will use a very different idea. The idea is to whenever we will encounter an element smaller than minElement instead of pushing the ‘elem’ to the stack and updating minElement, we will instead push (2*elem - minElement) to the stack and update minElement with ‘elem’.
During the pop operation, if we encounter any element smaller than minElement, we will know it is the same altered element that we pushed and it’s time to modify our minElement. We will return the minElement and update our minElement with (2*minElement - top Element). Too many maths involved here. Let's move on to the solution steps.
Solution steps
minElement if the stack is empty. Otherwise, it will compare the ‘elem’ with the minElement. If smaller, we will push (2*elem-minElement) instead to the stack and update minElement with ‘elem’.minElement, we will update our minElement with (2*minElement-top element).minElement. If yes, we will return minElement. Else we will return the last element pushed into the stack. (Think why?)getMin operation, we will simply return the value of minElement.Illustration for this solution
We will take the above approach and will insert 2, 4, -1 into the stack.
Insert 2 →stack is empty simply push 2. minElement is 2
Insert 4 → 4 > 2, push 4 to stack. minElement is still 2.
Insert -1, -1 < 2, push (2*elem — minElement) i.e. -4 to the stack. minElement is -1.
Pop top element i.e. -4, it is the time to change our minElement. minElement will be 2*minElement- top Element i.e. 2*-1-(-4) = 2.
Wow, that is exactly what we want.
Why this approach works?
If you have observed, we have taken two assumptions:
minElement was (2*minElement - y) which was used to make new minElement after deleting y, where y is the smaller number than current minElement that is to be deleted(pop operation).Let us try to prove this using mathematics:
Proving our point (i)
For simplicity let us take elem as e, minElement as m, previous minElement as p
e < m which implies e-m < 0
//Adding e to both sides
2*e - m < e
Thus, we can conclude:
2*elem - minElement < elem
Proving our point (ii)
//For simplicity let us take elem as e, minElement as m, previous minElement as p and n for new minElement
We know y was pushed as 2*e - p when e < current minElement
y = 2*e - p
// minElement was updated to e
m = e
n = 2*m - y
= 2*e - (2*e - p)
= p
So the new minElement is equal to previous minElement.
Hurrah! This is what we wanted.
Pseudo-code
class MinStack {
public:
vector <long int> stack
long int minimum
MinStack() {
//Constructor
}
//Push Operation
void push(int x) {
long y = (long)x
if(!stack.empty())
{
if(y<minimum) {
stack.push_back(2*y - minimum)
minimum = y
}
else
stack.push_back(y)
}
else {
stack.push_back(y)
minimum =y
}
}
//Pop Operation
void pop() {
if(stack.back() < minimum)
{
minimum = 2*minimum - stack.back();
stack.pop_back()
}
else
stack.pop_back()
}
//Top Operation
int top() {
if(!stack.empty())
if(stack.back() < minimum)
return minimum
else
return stack.back()
else
return -1
}
//getMin Operation
int getMin() {
return minimum
}
};
Complexity Analysis
Time Complexity: O(1)
Space Complexity: O(1)
Critical ideas to think!

Happy Coding!!!
AfterAcademy Tech
This is an interview problem asked in companies like Microsoft, Amazon, Adobe, Flipkart, etc. Here, we need to implement Queue data structure using another data structure Stack. This problem is meant for testing the data structure knowledge.

AfterAcademy Tech
Given a stack, you have to sort it in ascending order. You can use another stack if you need auxiliary space. The problem is asked in Google, Microsoft and Amazon and requires knowledge of Stack and recursion to solve it.

AfterAcademy Tech
Given a stack of integers st, write a program to reverse the stack using recursion. This problem will clear the concept of recursion.

AfterAcademy Tech
This is an interview problem asked by companies like Amazon. This problem is based on Greedy Algorithm and is one of the very basic problem for understanding Greedy Algorithms.
