155. Min Stack - Detailed Explanation

Free Coding Questions Catalog
Boost your coding skills with our essential coding questions catalog. Take a step towards a better tech career now!

Problem Statement

You are asked to design a stack that supports the following operations in constant time:

  • push(x) – Push element x onto the stack.
  • pop() – Remove the element on top of the stack.
  • top() – Get the top element.
  • getMin() – Retrieve the minimum element in the stack.

Example Inputs & Outputs:

  1. Example 1:

    • Operations:
      push(-2)
      push(0)
      push(-3)
      getMin() -> Returns -3.
      pop()
      top() -> Returns 0.
      getMin() -> Returns -2.
      
    • Explanation:
      After pushing -2, 0, and -3, the minimum element is -3. Once -3 is popped, the new minimum becomes -2.
  2. Example 2:

    • Operations:
      push(1)
      push(2)
      getMin() -> Returns 1.
      top() -> Returns 2.
      pop()
      getMin() -> Returns 1.
      
    • Explanation:
      Pushing 1 then 2, the minimum element is 1. Even after popping the top element (2), the minimum remains 1.
  3. Example 3:

    • Operations:
      push(3)
      push(4)
      push(2)
      push(1)
      getMin() -> Returns 1.
      pop()
      getMin() -> Returns 2.
      
    • Explanation:
      The stack’s minimum changes as elements are removed. Initially, it’s 1; after popping 1, the new minimum is 2.

Constraints:

  • All operations must be executed in constant time, (O(1)).
  • It is guaranteed that pop, top, and getMin will always be called on non-empty stacks.

Hints to Approach the Problem

  • Hint 1: Consider that if you use a regular stack, a call to getMin() would require scanning the entire stack (which is (O(n))). Think about a way to "remember" the minimum element as you push or pop elements.

  • Hint 2: One effective method is to use an auxiliary stack to keep track of the minimum values. Every time you push a new element, you compare it with the current minimum, and update the auxiliary structure accordingly.

Approaches

Approach 1: Brute Force (Not Optimal)

  • Idea:
    Use a normal stack for all elements and, for getMin(), iterate over the stack to find the minimum.
  • Downside:
    While push, pop, and top would run in constant time, getMin() would run in (O(n)) time, which violates the constant time requirement for all operations.

Approach 2: Two-Stack Method (Optimal)

  • Idea:
    Maintain two stacks:

    • Main Stack: Stores all the pushed elements.
    • Min Stack: Stores the current minimum at every push.
      • When you push an element, compare it with the top of the min stack.
        • If the new element is less than or equal to the current minimum, push it onto the min stack.
        • When popping, if the element removed is the same as the top of the min stack, also pop from the min stack.
  • How It Works:
    At any moment, the top of the min stack holds the minimum element of the main stack. This guarantees that getMin() is (O(1)).

Approach 3: Single Stack with Pairs

  • Idea:
    Instead of maintaining two separate stacks, you can use one stack that stores pairs: (value, current_min).

    • Every time you push a new element, you calculate the new minimum (using the current top of the stack, if any) and push the pair onto the stack.
    • Pop and top operations work as normal; getMin() simply reads the second element of the top pair.
  • Trade-off:
    This method uses slightly more space per element but still provides constant time operations.

Python Code

Python3
Python3

. . . .

Java Code

Java
Java

. . . .

Complexity Analysis

  • Time Complexity:
    All operations (push, pop, top, and getMin) run in (O(1)) time.

  • Space Complexity:
    In the worst case, the additional space for the min stack is (O(n)) where (n) is the number of elements in the stack (for example, if elements are pushed in non-increasing order).

Step-by-Step Walkthrough and Visual Example

Consider the following sequence on a Min Stack:

  1. Operation: push(5)
    • Main Stack: [5]
    • Min Stack: [5]
  2. Operation: push(3)
    • Main Stack: [5, 3]
    • Min Stack: [5, 3] (3 is less than 5, so it is added)
  3. Operation: push(7)
    • Main Stack: [5, 3, 7]
    • Min Stack: [5, 3] (7 is not less than or equal to 3, so min stack remains unchanged)
  4. Operation: getMin() returns the top of min stack: 3.
  5. Operation: pop() removes 7 from main stack.
  6. Operation: top() returns the new top of main stack: 3.
  7. Operation: pop() removes 3 from main stack and also from min stack since 3 equals the top of min stack.
  8. Operation: getMin() now returns 5, which is the current minimum.

Common Mistakes

  • Not Updating the Min Stack on Pop:
    Forgetting to pop the element from the min stack when the popped element is the current minimum can lead to an incorrect minimum value.

  • Using a Single Stack Without Extra Information:
    Attempting to calculate the minimum by scanning the stack every time getMin() is called results in (O(n)) time, violating the problem constraints.

  • Incorrect Comparison in Push:
    Ensure that when pushing a new element, the condition checks for "less than or equal" so that duplicate minimums are handled correctly.

  • Single Stack with Pairing:
    As mentioned, an alternative is to store each element as a pair (value, current_min) in a single stack.

  • Max Stack:
    A variation of this problem is to design a stack that retrieves the maximum element in constant time.

  • Other Stack Problems:
    Problems like "Valid Parentheses", "Evaluate Reverse Polish Notation", and "Design a Stack With Increment Operation" share similar concepts.

  • Implement Queue using Stacks:
    Practice using stacks to simulate queue operations.

  • Largest Rectangle in Histogram:
    Use a stack to solve this classic problem.

  • Daily Temperatures:
    A problem that utilizes stack concepts to find the next warmer day.

TAGS
leetcode
CONTRIBUTOR
Design Gurus Team
-

GET YOUR FREE

Coding Questions Catalog

Design Gurus Newsletter - Latest from our Blog
Boost your coding skills with our essential coding questions catalog.
Take a step towards a better tech career now!
Explore Answers
Related Courses
Grokking the Coding Interview: Patterns for Coding Questions
Grokking the Coding Interview Patterns in Java, Python, JS, C++, C#, and Go. The most comprehensive course with 476 Lessons.
Grokking Modern AI Fundamentals
Master the fundamentals of AI today to lead the tech revolution of tomorrow.
Grokking Data Structures & Algorithms for Coding Interviews
Unlock Coding Interview Success: Dive Deep into Data Structures and Algorithms.
Image
One-Stop Portal For Tech Interviews.
Copyright © 2025 Design Gurus, LLC. All rights reserved.
;