- Published on
leetcode-155 Min Stack
- Authors

- Name
- Gene Zhang
Key Concept: Auxiliary Stack for Tracking Minimum - Maintain two stacks: one for actual values, one for tracking minimum at each level. When pushing, also push current minimum onto min stack. This keeps getMin() at O(1).
Alternative: Store (value, current_min) pairs in a single stack.
# Design a stack that supports push, pop, top, and retrieving the minimum
# element in constant time.
# Implement the MinStack class with:
# - MinStack() initializes the stack object.
# - void push(int val) pushes val onto the stack.
# - void pop() removes the element on top of the stack.
# - int top() gets the top element of the stack.
# - int getMin() retrieves the minimum element in the stack.
# You must implement a solution with O(1) time complexity for each function.
#
# Example:
# Input: ["MinStack","push","push","push","getMin","pop","top","getMin"]
# [[],[-2],[0],[-3],[],[],[],[]]
# Output: [null,null,null,null,-3,null,0,-2]
#
# Constraints:
# -2^31 <= val <= 2^31 - 1
# pop, top and getMin will always be called on non-empty stacks.
class MinStack:
# Approach 1: Two stacks
def __init__(self):
self.stack = [] # Main stack
self.min_stack = [] # Stack tracking minimums
def push(self, val: int) -> None:
self.stack.append(val)
# Push current minimum onto min_stack
if not self.min_stack:
self.min_stack.append(val)
else:
self.min_stack.append(min(val, self.min_stack[-1]))
def pop(self) -> None:
self.stack.pop()
self.min_stack.pop()
def top(self) -> int:
return self.stack[-1]
def getMin(self) -> int:
return self.min_stack[-1]
# Approach 2: Single stack with pairs
class MinStack2:
def __init__(self):
# Stack stores (value, current_min) pairs
self.stack = []
def push(self, val: int) -> None:
if not self.stack:
self.stack.append((val, val))
else:
current_min = min(val, self.stack[-1][1])
self.stack.append((val, current_min))
def pop(self) -> None:
self.stack.pop()
def top(self) -> int:
return self.stack[-1][0]
def getMin(self) -> int:
return self.stack[-1][1]
# Approach 3: Space optimized (only store min when it changes)
class MinStack3:
def __init__(self):
self.stack = []
self.min_stack = []
def push(self, val: int) -> None:
self.stack.append(val)
# Only push to min_stack if it's a new minimum
if not self.min_stack or val <= self.min_stack[-1]:
self.min_stack.append(val)
def pop(self) -> None:
val = self.stack.pop()
# Pop from min_stack if we're removing the current minimum
if val == self.min_stack[-1]:
self.min_stack.pop()
def top(self) -> int:
return self.stack[-1]
def getMin(self) -> int:
return self.min_stack[-1]
# All operations: Time O(1), Space O(n)
#
# Key Pattern: Auxiliary data structure to track additional information
# Trade space for time to achieve O(1) operations
#
# Similar problems: Max Stack, Stack with Middle Element