Welcome to Subscribe On Youtube
Question
Formatted question description: https://leetcode.ca/all/155.html
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
.
Algorithm
Two stacks are used to achieve this, one stack is used to store the data that push in in order, and the other is used to store the smallest value that has occurred.
Code
-
class MinStack { Stack<Integer> sk = new Stack<>(); Stack<Integer> min = new Stack<>(); public void push(int x) { sk.push(x); // @note: if pushing duplicated, then the 2nd is missing if no "=" if (min.isEmpty() || min.peek() >= x) { min.push(x); } } public void pop() { int popVal = sk.pop(); if (popVal == min.peek()) { min.pop(); } } public int top() { return sk.peek(); } public int getMin() { return min.peek(); } } class MinStack_SortedList_ACed { Stack<Integer> sk; PriorityQueue<Integer> sorted; /** initialize your data structure here. */ public MinStack_SortedList_ACed() { sk = new Stack<>(); sorted = new PriorityQueue<>(); } public void push(int x) { sk.push(x); sorted.offer(x); // NlogN } public void pop() { int popped = sk.pop(); // remove by object, not by index // but, here remove() is o(N) operation sorted.remove(popped); } public int top() { return sk.peek(); } public int getMin() { return sorted.peek(); } } ############ class MinStack { private Deque<Integer> stk1 = new ArrayDeque<>(); private Deque<Integer> stk2 = new ArrayDeque<>(); /** initialize your data structure here. */ public MinStack() { stk2.push(Integer.MAX_VALUE); } public void push(int x) { stk1.push(x); stk2.push(Math.min(x, 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(x); * obj.pop(); * int param_3 = obj.top(); * int param_4 = obj.getMin(); */
-
// OJ: https://leetcode.com/problems/min-stack/ // Time: O(1) for all // Space: O(N) class MinStack { stack<int> mn, val; public: MinStack() {} void push(int x) { val.push(x); if (mn.empty() || mn.top() >= x) mn.push(x); } void pop() { if (val.top() == mn.top()) mn.pop(); val.pop(); } int top() { return val.top(); } int getMin() { return mn.top(); } };
-
class MinStack: def __init__(self): self.stk1 = [] self.stk2 = [inf] def push(self, x: int) -> None: self.stk1.append(x) self.stk2.append(min(x, self.stk2[-1])) def pop(self) -> None: self.stk1.pop() self.stk2.pop() def top(self) -> int: return self.stk1[-1] def getMin(self) -> int: return self.stk2[-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) 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 } /** initialize your data structure here. */ func Constructor() MinStack { return MinStack{[]int{}, []int{math.MaxInt32} } } func (this *MinStack) Push(x int) { this.stk1 = append(this.stk1, x) this.stk2 = append(this.stk2, min(x, 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] } func min(a, b int) int { if a < b { return a } return b } /** * Your MinStack object will be instantiated and called as such: * obj := Constructor(); * obj.Push(x); * obj.Pop(); * param_3 := obj.Top(); * param_4 := obj.GetMin(); */
-
class MinStack { stk1: number[]; stk2: number[]; constructor() { this.stk1 = []; this.stk2 = [Infinity]; } push(x: number): void { this.stk1.push(x); this.stk2.push(Math.min(x, 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() */
-
/** * initialize your data structure here. */ var MinStack = function () { this.stack = []; this.minStack = []; }; /** * @param {number} x * @return {void} */ MinStack.prototype.push = function (x) { this.stack.unshift(x); if (!this.minStack.length || this.minStack[0] >= x) { this.minStack.unshift(x); } }; /** * @return {void} */ MinStack.prototype.pop = function () { if (this.stack.shift() === this.minStack[0]) { this.minStack.shift(); } }; /** * @return {number} */ MinStack.prototype.top = function () { return this.stack[0]; }; /** * @return {number} */ MinStack.prototype.min = function () { return this.minStack[0]; }; /** * 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.min() */
-
public class MinStack { private Stack<int> stk1 = new Stack<int>(); private Stack<int> stk2 = new Stack<int>(); /** initialize your data structure here. */ 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 { stack: VecDeque<i32>, min_stack: VecDeque<i32>, } /** * `&self` means the method takes an immutable reference. * If you need a mutable reference, change it to `&mut self` instead. */ impl MinStack { /** initialize your data structure here. */ fn new() -> Self { Self { stack: VecDeque::new(), min_stack: VecDeque::new() } } fn push(&mut self, x: i32) { self.stack.push_back(x); if self.min_stack.is_empty() || *self.min_stack.back().unwrap() >= x { self.min_stack.push_back(x); } } fn pop(&mut self) { let val = self.stack.pop_back().unwrap(); if *self.min_stack.back().unwrap() == val { self.min_stack.pop_back(); } } fn top(&self) -> i32 { *self.stack.back().unwrap() } fn get_min(&self) -> i32 { *self.min_stack.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(); */