Stack with Minimum Element in JavaScript
Implement a stack data structure in JavaScript that supports all standard stack operations (push, pop, peek) and additionally allows retrieving the minimum element currently in the stack in O(1) time complexity. This is a common interview question that tests your understanding of data structures and how to optimize operations.
Problem Description
You need to design and implement a JavaScript class, let's call it MinStack. This class should behave like a regular stack but with an added getMin() method.
Key Requirements:
push(val): Pushes an elementvalonto the stack.pop(): Removes and returns the element at the top of the stack.peek(): Returns the element at the top of the stack without removing it.getMin(): Returns the current minimum element in the stack. This operation must have a time complexity of O(1).
Expected Behavior:
- When an element is pushed, the stack should update its internal state to correctly track the minimum element.
- When an element is popped, the minimum element tracking should also be updated.
getMin()should always return the smallest value currently present in the stack.- If the stack is empty,
pop()andpeek()should ideally returnundefinedor throw an error (specify your chosen behavior). ForgetMin(), it should also returnundefinedor throw an error.
Edge Cases to Consider:
- Pushing duplicate minimum values.
- Popping the current minimum value.
- An empty stack.
Examples
Example 1:
Input:
const minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); // Output: -3
minStack.pop();
minStack.peek(); // Output: 0
minStack.getMin(); // Output: -2
Output:
minStack.getMin()returns-3.minStack.peek()returns0.minStack.getMin()returns-2.
Explanation:
push(-2): Stack:[-2], Min:-2push(0): Stack:[-2, 0], Min:-2push(-3): Stack:[-2, 0, -3], Min:-3getMin(): Returns-3.pop(): Removes-3. Stack:[-2, 0], Min:-2(old min is still valid)peek(): Returns0.getMin(): Returns-2.
Example 2:
Input:
const minStack = new MinStack();
minStack.push(5);
minStack.push(2);
minStack.push(5);
minStack.push(1);
minStack.getMin(); // Output: 1
minStack.pop(); // removes 1
minStack.getMin(); // Output: 2
minStack.pop(); // removes 5
minStack.getMin(); // Output: 2
minStack.pop(); // removes 2
minStack.getMin(); // Output: 5
Output:
minStack.getMin()returns1.minStack.getMin()returns2.minStack.getMin()returns2.minStack.getMin()returns5.
Explanation:
push(5): Stack:[5], Min:5push(2): Stack:[5, 2], Min:2push(5): Stack:[5, 2, 5], Min:2push(1): Stack:[5, 2, 5, 1], Min:1getMin(): Returns1.pop(): Removes1. Stack:[5, 2, 5]. The next minimum is2.getMin(): Returns2.pop(): Removes5. Stack:[5, 2]. The next minimum is2.getMin(): Returns2.pop(): Removes2. Stack:[5]. The next minimum is5.getMin(): Returns5.
Example 3: Empty Stack
Input:
const minStack = new MinStack();
minStack.getMin(); // Output: undefined (or error)
minStack.pop(); // Output: undefined (or error)
Output:
minStack.getMin()returnsundefined.minStack.pop()returnsundefined.
Constraints
- The values pushed onto the stack will be integers.
- You may assume that
pop()andpeek()are called only when there is at least one element in the stack (if you choose not to handle empty stack explicitly by returningundefined). - The
getMin()operation must be O(1) time complexity. - Other operations (
push,pop,peek) can be O(1) or O(N) where N is the number of elements in the stack, but O(1) is preferred for an optimal solution.
Notes
- Think about how to store additional information with each element pushed onto the stack to efficiently track the minimum.
- Consider using an auxiliary data structure or augmenting the elements stored in the primary stack.
- Be mindful of the time complexity for
getMin().