Keeping Track of the Minimum: Calculating the Minimum Element in a Stack for Coding Interviews

Christopher Franklin
Weekly Python
Published in
2 min readMay 19, 2023

Introduction

One intriguing problem that often surfaces during coding interviews involves maintaining a stack data structure that, in addition to the usual push and pop operations, allows for retrieving the minimum element in constant time. At first, this might seem daunting given that stacks, a Last-In-First-Out (LIFO) data structure, don't usually provide direct access to elements not at the top. However, this problem can be elegantly solved using an additional stack. This blog post will guide you through this process in Python.

Understanding the Problem

The challenge here is to design a stack such that you can efficiently (i.e., in constant time) perform the following operations:

  1. push(x): Push element x onto stack.
  2. pop(): Removes the element on top of the stack.
  3. top(): Get the top element.
  4. getMin(): Retrieve the minimum element in the stack.

Solution: Stack with an Auxiliary Stack

We'll implement our MinStack using two stacks: a main stack to hold the elements and an auxiliary stack (minStack) to keep track of the minimum elements.

Here's how it works:

  • For push(x), we add the element to the main stack. If the minStack is empty or x is less than or equal to the top element of minStack, we also push x to minStack.
  • For pop(), we remove the top element from the main stack. If the popped element is the same as the top element of minStack, we also pop from minStack.
  • For top(), we simply return the top element from the main stack.
  • For getMin(), we return the top element from minStack, which is always the minimum element.

Here's the Python code for our MinStack:

class MinStack:
def __init__(self):
self.stack = []
self.minStack = []

def push(self, x):
self.stack.append(x)
if not self.minStack or x <= self.minStack[-1]:
self.minStack.append(x)

def pop(self):
if self.stack:
x = self.stack.pop()
if x == self.minStack[-1]:
self.minStack.pop()
return x

def top(self):
if self.stack:
return self.stack[-1]

def getMin(self):
if self.minStack:
return self.minStack[-1]

Testing the MinStack Implementation

Let's put our MinStack to the test:

minStack = MinStack()
minStack.push(-2)
minStack.push(0)
minStack.push(-3)
print(minStack.getMin()) # Returns -3
minStack.pop()
print(minStack.top()) # Returns 0
print(minStack.getMin()) # Returns -2

Conclusion

This problem highlights how the clever use of data structures can simplify seemingly complex tasks. Remember that while this specific problem might not show up in every interview, the fundamental principles involved are widely applicable. Therefore, gaining a deep understanding of data structures and how to use them is an invaluable tool in your interview preparation. As always, practice is key to mastery. Happy coding!

P.S. Want weekly python coding challenges and news? Sign up for the newsletter to get them directly in your inbox: https://weeklypython.substack.com/welcome

--

--