Consider a Min Stack that supports push, pop, and getMin operations. What is the output of the getMin() calls after the following operations?
push(5), push(3), push(7), getMin(), pop(), getMin(), pop(), getMin()
package main import "fmt" type MinStack struct { stack []int minStack []int } func (ms *MinStack) Push(x int) { ms.stack = append(ms.stack, x) if len(ms.minStack) == 0 || x <= ms.minStack[len(ms.minStack)-1] { ms.minStack = append(ms.minStack, x) } } func (ms *MinStack) Pop() { if len(ms.stack) == 0 { return } top := ms.stack[len(ms.stack)-1] ms.stack = ms.stack[:len(ms.stack)-1] if top == ms.minStack[len(ms.minStack)-1] { ms.minStack = ms.minStack[:len(ms.minStack)-1] } } func (ms *MinStack) GetMin() int { if len(ms.minStack) == 0 { return -1 } return ms.minStack[len(ms.minStack)-1] } func main() { ms := MinStack{} ms.Push(5) ms.Push(3) ms.Push(7) fmt.Println(ms.GetMin()) ms.Pop() fmt.Println(ms.GetMin()) ms.Pop() fmt.Println(ms.GetMin()) }
Remember the minStack keeps track of the minimum values at each push.
After pushing 5, 3, 7, the minimum is 3. After popping 7, minimum remains 3. After popping 3, minimum becomes 5.
Why do we use a separate stack (minStack) alongside the main stack in a Min Stack implementation?
Think about how to get the minimum element quickly without scanning the whole stack.
The auxiliary stack stores the minimum element at each push so getMin() can return in constant time.
What error will occur when running this Pop method of Min Stack?
func (ms *MinStack) Pop() {
top := ms.stack[len(ms.stack)-1]
ms.stack = ms.stack[:len(ms.stack)-1]
if top == ms.minStack[len(ms.minStack)-1] {
ms.minStack = ms.minStack[:len(ms.minStack)-1]
}
}What happens if Pop is called on an empty stack?
The method does not check if the stack is empty before accessing the last element, causing an index out of range panic.
What is the output of the getMin() calls after this sequence?
push(2), push(0), push(3), push(0), getMin(), pop(), getMin(), pop(), getMin(), pop(), getMin()
package main import "fmt" type MinStack struct { stack []int minStack []int } func (ms *MinStack) Push(x int) { ms.stack = append(ms.stack, x) if len(ms.minStack) == 0 || x <= ms.minStack[len(ms.minStack)-1] { ms.minStack = append(ms.minStack, x) } } func (ms *MinStack) Pop() { if len(ms.stack) == 0 { return } top := ms.stack[len(ms.stack)-1] ms.stack = ms.stack[:len(ms.stack)-1] if top == ms.minStack[len(ms.minStack)-1] { ms.minStack = ms.minStack[:len(ms.minStack)-1] } } func (ms *MinStack) GetMin() int { if len(ms.minStack) == 0 { return -1 } return ms.minStack[len(ms.minStack)-1] } func main() { ms := MinStack{} ms.Push(2) ms.Push(0) ms.Push(3) ms.Push(0) fmt.Println(ms.GetMin()) ms.Pop() fmt.Println(ms.GetMin()) ms.Pop() fmt.Println(ms.GetMin()) ms.Pop() fmt.Println(ms.GetMin()) }
Track the minimum after each pop carefully.
The minimum stays 0 until the last pop, then it becomes 2.
Given a sequence of n push and pop operations on a Min Stack, what is the minimum number of times the auxiliary minStack is updated (push or pop) to maintain correct minimum tracking?
Consider that minStack updates happen on some pushes and some pops.
Each push can add to minStack if new min, and each pop can remove from minStack if top equals min. So total updates can be up to 2n.
