class QueueMin(object): def __init__(self): self.q = Queue() self.min = None # All queue items are always in Q, def __len__(self): return self.q.size def __repr__(self): return "{%r}/Min: %r" % (self.q, self.min) def __str__(self): return str(self.q) def minimum(self): return self.min # Add to Q and return def enqueue(self, x): self.q.enqueue(x) # update min # if min is None => this is the first item to be enqueued self.min = min(x, self.min) if self.min else x # Dequeue() from Q # if popped item was minima, Re-enqueue all items while calculating new minima def dequeue(self): # Helper function to re-enqueue all items from Queue, Q back into itself # while updating new minima def reenqueue(q): minima = q.front() for i in range(len(q)): x = q.dequeue() q.enqueue(x) minima = min(x, minima) return minima # SLL raises UnderFlowError if Q is empty item = self.q.dequeue() # We just dequeued the last item from the queue # restore min to be None if not self.q: self.min = None elif item == self.min: # Update min if item == minima self.min = reenqueue(self.q) return item # Return the front of Q def front(self): return self.q.front() # Return the back of Q def back(self): return self.q.back()
class Stack(object): def __init__(self): self.q1 = Queue() self.q2 = Queue() # peek what's at the top of the stack # Stack-order is preserved in Q1 # Stack's top would be at the front of Q1 def top(self): return self.q1.front() def __len__(self): return self.q1.size # Add x to Q2 # Move everything from Q1 to Q2, so Q2 preserves stack-order # swap Q1, Q2 def push(self, x): # Helper function to move all items from queue a to queue b def move(a, b): while a: b.enqueue(a.dequeue()) self.q2.enqueue(x) # Move items from q1 to q2 move(self.q1, self.q2) # Swap Q1, Q2 self.q1, self.q2 = self.q2, self.q1 # Q1 has items in stack-order # Just dequeue from Q1 and return def pop(self): return self.q1.dequeue() def __str__(self): return str(self.q1) def __repr__(self): return "{%r , %r}" %(self.q1, self.q2)
class Stack(object): def __init__(self): self.q = Queue() # peek what's at the top of the stack # Stack-order is preserved in Q # Stack's top would be at the front of Q def top(self): return self.q.front() def __len__(self): return self.q.size # Enqueue x into Q # re-enqueue (n-1) items from Q, and re-enqueue back to Q def push(self, x): # Helper function to reenqueue 'n' items from queue a back into it def reenqueue(a, n): for i in range(n): a.enqueue(a.dequeue()) self.q.enqueue(x) # reenqueue (n-1) items from q reenqueue(self.q, self.q.size-1) # Just dequeue from Q as it preserves stack-order def pop(self): # Dequeue from the front of q return self.q.dequeue() # Q preserves stack-order, Just return Q as-is def __str__(self): return str(self.q) def __repr__(self): return "%r" %(self.q)
class Stack(object): def __init__(self): self.q1 = Queue() self.q2 = Queue() # peek what's at the top of the stack # Stack-order is preserved in Q1 # Stack's top would be at the front of Q1 def top(self): return self.q1.front() def __len__(self): return self.q1.size # Add x to Q2 # Move everything from Q1 to Q2, so Q2 preserves stack-order # swap Q1, Q2 def push(self, x): # Helper function to move all items from queue a to queue b def move(a, b): while a: b.enqueue(a.dequeue()) self.q2.enqueue(x) # Move items from q1 to q2 move(self.q1, self.q2) # Swap Q1, Q2 self.q1, self.q2 = self.q2, self.q1 # Q1 has items in stack-order # Just dequeue from Q1 and return def pop(self): return self.q1.dequeue() def __str__(self): return str(self.q1) def __repr__(self): return "{%r , %r}" % (self.q1, self.q2)
class Stack(object): def __init__(self): self.q = Queue() # peek what's at the top of the stack # Stack-order is preserved in Q # Stack's top would be at the front of Q def top(self): return self.q.front() def __len__(self): return self.q.size # Enqueue x into Q # re-enqueue (n-1) items from Q, and re-enqueue back to Q def push(self, x): # Helper function to reenqueue 'n' items from queue a back into it def reenqueue(a, n): for i in range(n): a.enqueue(a.dequeue()) self.q.enqueue(x) # reenqueue (n-1) items from q reenqueue(self.q, self.q.size - 1) # Just dequeue from Q as it preserves stack-order def pop(self): # Dequeue from the front of q return self.q.dequeue() # Q preserves stack-order, Just return Q as-is def __str__(self): return str(self.q) def __repr__(self): return "%r" % (self.q)
def right_view(self, aggregate_fn=_default_printfn, **kwargs): if not self.root: return q = Queue() q.enqueue((0, self.root)) while q.length() != 0: curr_level, node = q.dequeue() q.enqueue((curr_level + 1, node.left)) if node.left else None q.enqueue((curr_level + 1, node.right)) if node.right else None # peek next node in the queue to see if this is the last node in the current level # if yes, print it try: (level, next_entry) = q.front() except UnderFlowError: (level, next_entry) = (None, None) # Queue is either empty, in which case this is the rightmost node in the last level # *OR*, next entry in the queue is for the level after this one, so this is the rightmost in the current level # In both cases, current node would be visible in a right-view. if (not next_entry) or (level > curr_level): aggregate_fn(kwargs, node.value)
class QueueMin(object): def __init__(self): self.q1 = Queue() self.dq2 = Deque() self.min = None # All queue items are always in Q1, # DQ2 is merely used to store relative order of minimas def __len__(self): return self.q1.size def __repr__(self): return "{%r , %r}/Min: %r" %(self.q1, self.dq2, self.min) def __str__(self): return str(self.q1) def minimum(self): return self.min # Add item to Q1 def enqueue(self, x): self.q1.enqueue(x) # update min # if min is None => this is the first item to be enqueued self.min = min(x, self.min) if self.min else x # Update DQ2 to maintain the order of minimas, # so when a minima is removed, the next minima can be immediately retrieved # remove everything from the back of DQ2 as long as it is > item x while self.dq2 and self.dq2.back() > x: self.dq2.pop_back() # Add item x to DQ2 self.dq2.push_back(x) # Dequeue() from Q1 # DQ2 stores relative order of minimas for the current queue items # if popped item was minima, update minima to DQ2 new head() def dequeue(self): # SLL raises UnderFlowError if Q2 is empty item = self.q1.dequeue() # item removed was the current minima, remove it from DQ2 as well # item would be found in the head of DQ2 if item == self.min: self.dq2.pop_front() # Also, update new min which would be the new head of DQ2 after removing the current minima # NOTE: self.min should be None, if dq2 is empty - ie, we just removed the last item in the Queue self.min = self.dq2.front() if self.dq2 else None return item # Return the front of Q1 def front(self): return self.q1.front() # Return the back of Q1 def back(self): return self.q1.back()
class QueueMin(object): def __init__(self): self.q = Queue() self.min = None # All queue items are always in Q, def __len__(self): return self.q.size def __repr__(self): return "{%r}/Min: %r" %(self.q, self.min) def __str__(self): return str(self.q) def minimum(self): return self.min # Add to Q and return def enqueue(self, x): self.q.enqueue(x) # update min # if min is None => this is the first item to be enqueued self.min = min(x, self.min) if self.min else x # Dequeue() from Q # if popped item was minima, Re-enqueue all items while calculating new minima def dequeue(self): # Helper function to re-enqueue all items from Queue, Q back into itself # while updating new minima def reenqueue(q): minima = q.front() for i in range(len(q)): x = q.dequeue() q.enqueue(x) minima = min(x, minima) return minima # SLL raises UnderFlowError if Q is empty item = self.q.dequeue() # We just dequeued the last item from the queue # restore min to be None if not self.q: self.min = None elif item == self.min: # Update min if item == minima self.min = reenqueue(self.q) return item # Return the front of Q def front(self): return self.q.front() # Return the back of Q def back(self): return self.q.back()
class QueueMin(object): def __init__(self): self.q1 = Queue() self.q2 = Queue() self.min = None # All queue items are always in Q1, Q2 is merely used to move queue elements and update minima # after which Q2 is renamed Q1 def __len__(self): return self.q1.size def __repr__(self): return "{%r , %r}/Min: %r" % (self.q1, self.q2, self.min) def __str__(self): return str(self.q1) def minimum(self): return self.min # Add to Q1 and return def enqueue(self, x): self.q1.enqueue(x) # update min # if min is None => this is the first item to be enqueued self.min = min(x, self.min) if self.min else x # Dequeue() from Q2 # if popped item was minima, use Q2 to move all items while calculating new minima def dequeue(self): # Helper function to move all items from Queue, A to Queue, B # while updating new minima def move(a, b): minima = a.front() while a: x = a.dequeue() b.enqueue(x) minima = min(x, minima) return minima # SLL raises UnderFlowError if Q2 is empty item = self.q1.dequeue() # We just dequeued the last item from the queue # restore min to be None if not self.q1: self.min = None elif item == self.min: # Update min if item == minima self.min = move(self.q1, self.q2) # swap Q1, Q2 self.q1, self.q2 = self.q2, self.q1 return item # Return the front of Q1 def front(self): return self.q1.front() # Return the back of Q1 def back(self): return self.q1.back()