# CSPT21 Lecture 10 ## [Min Stack](https://leetcode.com/problems/min-stack/) ``` from collections import deque class MinStack: """ Understand myStack = MinStack() myStack.push(1) myStack.push(2) myStack.push(3) print(myStack.top()) # 3 print(myStack.getMin()) # 1 print(myStack.pop()) # 3 print(myStack.top()) # 2 myStack.pop() # 2 myStack.pop() # 1 myStack.top() # inf myStack.getMin() # inf Plan Use minVal instance property to keep track of min val when pushing/popping the stack When pushing, keep track if there's a lower value When popping, keep track whether or not the value that is about to get popped is the lowest value if it's the lowest, then update minVal to be the next lowest value """ # O(1) def __init__(self): """ initialize your data structure here. """ self.stack = deque() self.minVal = float("inf") # O(1) def push(self, val: int) -> None: if val < self.minVal: self.minVal = val self.stack.append(val) # O(n) def pop(self) -> None: val = self.stack.pop() if val == self.minVal: if len(self.stack) > 0: self.minVal = min(self.stack) else: self.minVal = float("inf") def top(self) -> int: return self.stack[-1] def getMin(self) -> int: return self.minVal # Your MinStack object will be instantiated and called as such: # obj = MinStack() # obj.push(val) # obj.pop() # param_3 = obj.top() # param_4 = obj.getMin() ``` ## [Implement Stack Using Queues](https://leetcode.com/problems/implement-stack-using-queues/) ``` from collections import deque class MyStack: """ Understand myStack = MyStack() myStack.push(1) myStack.push(2) myStack.push(3) myStack.top() # 3 myStack.pop() # 3 myStack.top() # 2 myStack.pop() # 2 myStack.pop() # 1 myStack.pop() # None Plan push - enqueue onto our queue pop - transfer all elements in queue1 onto queue2 (except the last element). The last element is the topmost element of the stack. Dequeue it and return it """ def __init__(self): """ Initialize your data structure here. """ self.queue = deque() def push(self, x: int) -> None: """ Push element x onto stack. """ self.queue.append(x) def pop(self) -> int: """ Removes the element on top of the stack and returns that element. """ if len(self.queue) == 0: return float("inf") temp = deque() while len(self.queue) > 1: temp.append(self.queue.popleft()) lastElement = self.queue.popleft() self.queue = temp return lastElement def top(self) -> int: """ Get the top element. """ if len(self.queue) == 0: return float("inf") temp = deque() while len(self.queue) > 1: temp.append(self.queue.popleft()) lastElement = self.queue.popleft() temp.append(lastElement) self.queue = temp return lastElement def empty(self) -> bool: """ Returns whether the stack is empty. """ return len(self.queue) == 0 # Your MyStack object will be instantiated and called as such: # obj = MyStack() # obj.push(x) # param_2 = obj.pop() # param_3 = obj.top() # param_4 = obj.empty() ``` ## Sandbox ``` from collections import deque class Queue: def __init__(self): self.myDeque = deque() def enqueue(value): self.myDeque.append(value) def dequeue(): return self.myDeque.popleft() def peek(): return self.myDeque[0] class QueueUsingLists: def __init__(self): self.myList = [] def enqueue(value): self.myList.append(value) def dequeue(): return self.myList.pop(0) class Stack: def __init__(self): self.d = deque() # O(1) def push(self, value): self.d.append(value) # O(1) def pop(self): return self.d.pop() class LinkedList: def __init__(): pass def addToHead(value): pass def removeFromHead(): pass class StackUsingLinkedLists: def __init__(self): self.linkedList = LinkedList() # O(1) def push(self, value): self.linkedList.addToHead(value) # O(1) def pop(self): return self.linkedList.removeFromHead() class StackUsingLists: def __init__(self): self.myList = [] # O(n) def push(self, value): self.myList.append(value) # O(n) def pop(self): return self.myList.pop() ```