Consider a min stack that supports push, pop, top, and getMin operations.
Given the following operations, what is the output of getMin() after all operations?
push(5)
push(3)
push(7)
pop()
getMin()
class MinStack { private stack: number[] = []; private minStack: number[] = []; push(x: number): void { this.stack.push(x); if (this.minStack.length === 0 || x <= this.minStack[this.minStack.length - 1]) { this.minStack.push(x); } } pop(): void { const val = this.stack.pop(); if (val === this.minStack[this.minStack.length - 1]) { this.minStack.pop(); } } top(): number | undefined { return this.stack[this.stack.length - 1]; } getMin(): number | undefined { return this.minStack[this.minStack.length - 1]; } } const minStack = new MinStack(); minStack.push(5); minStack.push(3); minStack.push(7); minStack.pop(); console.log(minStack.getMin());
Remember that getMin() returns the smallest value currently in the stack.
After pushing 5, 3, and 7, the stack is [5, 3, 7]. Popping removes 7, so the stack is [5, 3]. The minimum is 3.
Using the same min stack design, what is the top element after the following operations?
push(2)
push(0)
push(3)
push(0)
pop()
getMin()
pop()
top()
class MinStack { private stack: number[] = []; private minStack: number[] = []; push(x: number): void { this.stack.push(x); if (this.minStack.length === 0 || x <= this.minStack[this.minStack.length - 1]) { this.minStack.push(x); } } pop(): void { const val = this.stack.pop(); if (val === this.minStack[this.minStack.length - 1]) { this.minStack.pop(); } } top(): number | undefined { return this.stack[this.stack.length - 1]; } getMin(): number | undefined { return this.minStack[this.minStack.length - 1]; } } const minStack = new MinStack(); minStack.push(2); minStack.push(0); minStack.push(3); minStack.push(0); minStack.pop(); minStack.getMin(); minStack.pop(); console.log(minStack.top());
Track the stack and min stack carefully after each operation.
After the operations, the stack is [2, 0, 3]. The top is 3, but after popping twice, the top becomes 0.
Look at this min stack code snippet. It does not always return the correct minimum after pop operations. Why?
class MinStack {
private stack: number[] = [];
private minStack: number[] = [];
push(x: number): void {
this.stack.push(x);
if (this.minStack.length === 0 || x < this.minStack[this.minStack.length - 1]) {
this.minStack.push(x);
}
}
pop(): void {
const val = this.stack.pop();
if (val === this.minStack[this.minStack.length - 1]) {
this.minStack.pop();
}
}
getMin(): number | undefined {
return this.minStack[this.minStack.length - 1];
}
}Think about what happens when duplicate minimum values are pushed.
Using '<' instead of '<=' means equal minimum values are not pushed to minStack. When popping one minimum, the minStack loses track of the other equal minimum.
Which approach reduces extra space used by the min stack while still supporting getMin() in O(1) time?
Think about storing less data but still being able to find minimum quickly.
Storing differences allows reconstructing minimum without extra stack space for each element, optimizing space.
For a min stack supporting push, pop, top, and getMin, what is the time complexity of each operation?
Consider how the min stack tracks minimum values.
Using an auxiliary stack to track minimum allows all operations to run in constant time.
