Welcome to Subscribe On Youtube
155. Min Stack
Description
Design a stack that supports push, pop, top, and retrieving the minimum element in constant time.
Implement the MinStack
class:
MinStack()
initializes the stack object.void push(int val)
pushes the elementval
onto the stack.void pop()
removes the element on the 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 1:
Input ["MinStack","push","push","push","getMin","pop","top","getMin"] [[],[-2],[0],[-3],[],[],[],[]] Output [null,null,null,null,-3,null,0,-2] Explanation MinStack minStack = new MinStack(); minStack.push(-2); minStack.push(0); minStack.push(-3); minStack.getMin(); // return -3 minStack.pop(); minStack.top(); // return 0 minStack.getMin(); // return -2
Constraints:
-231 <= val <= 231 - 1
- Methods
pop
,top
andgetMin
operations will always be called on non-empty stacks. - At most
3 * 104
calls will be made topush
,pop
,top
, andgetMin
.
Solutions
To implement a Min Stack (LeetCode problem 155), which supports push, pop, top, and retrieving the minimum element in constant time, you can maintain two stacks: one to store all the elements (the main stack) and another to store the minimum elements (the min stack). The min stack helps in keeping track of the minimum elements at any given point, aligning with the operations performed on the main stack.
Explanation:
- Initialization: Two empty lists are initialized;
self.stack
serves as the main stack, andself.min_stack
keeps track of the minimum values. - Push: When a new value is pushed onto the stack, it is always added to
self.stack
. It is also added toself.min_stack
ifself.min_stack
is empty or if the new value is less than or equal to the current minimum (the last element ofself.min_stack
). - Pop: When popping a value from the stack, if the value being popped is the current minimum (i.e., it matches the last element in
self.min_stack
), it is also popped fromself.min_stack
. - Top: The last element of
self.stack
is returned as the top element of the stack. - GetMin: The last element of
self.min_stack
, which is the current minimum, is returned.
This implementation ensures that all operations—push
, pop
, top
, and getMin
— run in constant time, satisfying the problem’s constraints.
-
class MinStack { private Deque<Integer> stk1 = new ArrayDeque<>(); private Deque<Integer> stk2 = new ArrayDeque<>(); public MinStack() { stk2.push(Integer.MAX_VALUE); } public void push(int val) { stk1.push(val); stk2.push(Math.min(val, stk2.peek())); } public void pop() { stk1.pop(); stk2.pop(); } public int top() { return stk1.peek(); } public int getMin() { return stk2.peek(); } } /** * Your MinStack object will be instantiated and called as such: * MinStack obj = new MinStack(); * obj.push(val); * obj.pop(); * int param_3 = obj.top(); * int param_4 = obj.getMin(); */
-
class MinStack { public: MinStack() { stk2.push(INT_MAX); } void push(int val) { stk1.push(val); stk2.push(min(val, stk2.top())); } void pop() { stk1.pop(); stk2.pop(); } int top() { return stk1.top(); } int getMin() { return stk2.top(); } private: stack<int> stk1; stack<int> stk2; }; /** * Your MinStack object will be instantiated and called as such: * MinStack* obj = new MinStack(); * obj->push(val); * obj->pop(); * int param_3 = obj->top(); * int param_4 = obj->getMin(); */
-
class MinStack: def __init__(self): self.sk = [] self.minsk = [inf] # trick, avoid later empty-check for min-stack def push(self, x: int) -> None: self.sk.append(x) self.minsk.append(min(x, self.minsk[-1])) def pop(self) -> None: if not self.sk: return self.sk.pop() self.minsk.pop() def top(self) -> int: return self.sk[-1] def getMin(self) -> int: return self.minsk[-1] # Your MinStack object will be instantiated and called as such: # obj = MinStack() # obj.push(x) # obj.pop() # param_3 = obj.top() # param_4 = obj.getMin() ############ class MinStack: def __init__(self): self.sk = [] self.minsk = [] def push(self, val: int) -> None: self.sk.append(val) # empty check self.minsk.append(val if not self.minsk else min(val, self.minsk[-1])) def pop(self) -> None: if not self.sk: return self.sk.pop() self.minsk.pop() def top(self) -> int: return self.sk[-1] def getMin(self) -> int: return self.minsk[-1] # optimize above, using only 1 stack, with stack element as tuple: (val, its associated min) class MinStack: def __init__(self): self._stack = [] def push(self, x: int) -> None: cur_min = self.getMin() if x < cur_min: cur_min = x self._stack.append((x, cur_min)) def pop(self) -> None: self._stack.pop() def top(self) -> int: if not self._stack: return None else: return self._stack[-1][0] def getMin(self) -> int: if not self._stack: return float('inf') else: return self._stack[-1][1]
-
type MinStack struct { stk1 []int stk2 []int } func Constructor() MinStack { return MinStack{[]int{}, []int{math.MaxInt32} } } func (this *MinStack) Push(val int) { this.stk1 = append(this.stk1, val) this.stk2 = append(this.stk2, min(val, this.stk2[len(this.stk2)-1])) } func (this *MinStack) Pop() { this.stk1 = this.stk1[:len(this.stk1)-1] this.stk2 = this.stk2[:len(this.stk2)-1] } func (this *MinStack) Top() int { return this.stk1[len(this.stk1)-1] } func (this *MinStack) GetMin() int { return this.stk2[len(this.stk2)-1] } /** * Your MinStack object will be instantiated and called as such: * obj := Constructor(); * obj.Push(val); * obj.Pop(); * param_3 := obj.Top(); * param_4 := obj.GetMin(); */
-
class MinStack { stk1: number[]; stk2: number[]; constructor() { this.stk1 = []; this.stk2 = [Infinity]; } push(val: number): void { this.stk1.push(val); this.stk2.push(Math.min(val, this.stk2[this.stk2.length - 1])); } pop(): void { this.stk1.pop(); this.stk2.pop(); } top(): number { return this.stk1[this.stk1.length - 1]; } getMin(): number { return this.stk2[this.stk2.length - 1]; } } /** * Your MinStack object will be instantiated and called as such: * var obj = new MinStack() * obj.push(x) * obj.pop() * var param_3 = obj.top() * var param_4 = obj.getMin() */
-
var MinStack = function () { this.stk1 = []; this.stk2 = [Infinity]; }; /** * @param {number} val * @return {void} */ MinStack.prototype.push = function (val) { this.stk1.push(val); this.stk2.push(Math.min(this.stk2[this.stk2.length - 1], val)); }; /** * @return {void} */ MinStack.prototype.pop = function () { this.stk1.pop(); this.stk2.pop(); }; /** * @return {number} */ MinStack.prototype.top = function () { return this.stk1[this.stk1.length - 1]; }; /** * @return {number} */ MinStack.prototype.getMin = function () { return this.stk2[this.stk2.length - 1]; }; /** * Your MinStack object will be instantiated and called as such: * var obj = new MinStack() * obj.push(val) * obj.pop() * var param_3 = obj.top() * var param_4 = obj.getMin() */
-
public class MinStack { private Stack<int> stk1 = new Stack<int>(); private Stack<int> stk2 = new Stack<int>(); public MinStack() { stk2.Push(int.MaxValue); } public void Push(int x) { stk1.Push(x); stk2.Push(Math.Min(x, GetMin())); } public void Pop() { stk1.Pop(); stk2.Pop(); } public int Top() { return stk1.Peek(); } public int GetMin() { return stk2.Peek(); } } /** * Your MinStack object will be instantiated and called as such: * MinStack obj = new MinStack(); * obj.Push(x); * obj.Pop(); * int param_3 = obj.Top(); * int param_4 = obj.GetMin(); */
-
use std::collections::VecDeque; struct MinStack { stk1: VecDeque<i32>, stk2: VecDeque<i32>, } /** * `&self` means the method takes an immutable reference. * If you need a mutable reference, change it to `&mut self` instead. */ impl MinStack { fn new() -> Self { Self { stk1: VecDeque::new(), stk2: VecDeque::new() } } fn push(&mut self, x: i32) { self.stk1.push_back(x); if self.stk2.is_empty() || *self.stk2.back().unwrap() >= x { self.stk2.push_back(x); } } fn pop(&mut self) { let val = self.stk1.pop_back().unwrap(); if *self.stk2.back().unwrap() == val { self.stk2.pop_back(); } } fn top(&self) -> i32 { *self.stk1.back().unwrap() } fn get_min(&self) -> i32 { *self.stk2.back().unwrap() } }/** * Your MinStack object will be instantiated and called as such: * let obj = MinStack::new(); * obj.push(x); * obj.pop(); * let ret_3: i32 = obj.top(); * let ret_4: i32 = obj.get_min(); */