def insert(self, num): if len(self.right) == len(self.left): push(self.left, -num) push(self.right, -pop(self.left)) else: push(self.right, num) push(self.left, -pop(self.right))
def minMeetingRooms(self, intervals: List[List[int]]) -> int: # base case - If there is no meeting to schedule then no room needs to be allocated. if not intervals: return 0 # The heap initialization free_rooms = [] # Sort the meetings in increasing order of their start time. intervals.sort(key=lambda x: x[0]) # Add the first meeting. We have to give a new room to the first meeting. push(free_rooms, intervals[0][1]) # For all the remaining meeting rooms for i in intervals[1:]: # end time in heap <= start time of interval if free_rooms[0] <= i[0]: pop(free_rooms) # for the existing room or the new room push(free_rooms, i[1]) return len(free_rooms)
def main(): line = lambda: stdin.readline().split() n, k = map(int, line()) # Patients patients = [] # Accidents accidents = {} # Times times = [] # Output list for fast printing outs = [] # Read in input for _ in range(n): inp = line() if inp[0] == "1": _, t, name, s = inp patients.append(tup(int(s), int(t), name)) elif inp[0] == "2": times.append(int(inp[1])) else: _, t, name = inp accidents[name] = int(t) # t values given in increasing order # Check the last time value to get the severity cost of EVERY patient # Because extra time added after the first time they can be served is equal for all patients, # Adding them as soon as they are available alleviates the need to update the cost later last_time = times[-1] for patient in patients: patient.s += (last_time - patient.t) * k # Use a heap to store all patients who can currently be served # Update the heap at each new serve-time q = [] # Index for the current patient i = 0 for j in range(len(times)): curr_time = times[j] # Find all patients who can now be served at this time while (i < len(patients) and patients[i].t <= curr_time): push(q, patients[i]) i += 1 # Find the best patient to serve, or take a break if there are none while (q and q[0].name in accidents and accidents[q[0].name] <= curr_time): # Remove patients who have had accidents and must leave the clinic pop(q) if q: best = pop(q) outs.append(best.name) else: outs.append("doctor takes a break") # Print all output at once, helps for large output sizes print("\n".join(outs))
def huffman(freq): global tree if len(freq) == 2: expand(freq[0], freq[1]) else: a = pop(freq) b = pop(freq) push(freq, (a[0] + b[0], a[1] + " " + b[1])) huffman(freq) expand(a, b)
def k_largest(stream, k): q = [] for elem in stream: if len(q) < k: push(q, elem) elif q[0] < elem: pop(q) push(q, elem) return q
def findKthLargest(self, nums: List[int], k: int) -> int: # list to act as min heap hq = [] # adding k elements to the heap for i in range(len(nums)): push(hq, nums[i]) # if elements in heap exceed k remove the smallest if len(hq) > k: pop(hq) # returning the smallest element return hq[0]
def solution(o, i=0, sh=set(), nh=[], xh=[]): for e in o: if (v := e.split(" "))[0] == "I": push(nh, (int(v[1]), i)) push(xh, (-int(v[1]), i)) sh.add(i) i += 1 elif sh: m = xh if v[1] == "1" else nh while (k := pop(m))[1] not in sh: pass
def connect_n_ropes(ropes): heap = [] for r in ropes: push(heap, r) while len(heap) > 1: first = pop(heap) second = pop(heap) push(heap, first + second) return heap[0]
def add(self, val): push(self.secondHalf, val) if (len(self.secondHalf) > len(self.firstHalf) + 1): push(self.firstHalf, -pop(self.secondHalf)) if (len(self.firstHalf) and self.secondHalf[0] < -self.firstHalf[0]): push(self.firstHalf, -pop(self.secondHalf)) if (len(self.secondHalf) + 1 < len(self.firstHalf)): push(self.secondHalf, -pop(self.firstHalf)) return self.getMedian()
def medians(numbers): numbers = iter(numbers) left, right = [], [] while True: #odd items push(left, -next(numbers)) push(right, -pop(left)) yield right[0] #even items push(right, next(numbers)) push(left, -pop(right)) yield (right[0] - left[0])/2.0
def addNum(self, x): """ :type num: int :rtype: None """ if len(self.right) == len(self.left): push(self.right, x) _min = pop(self.right) push(self.left, -_min) else: push(self.left, - x ) _max = pop(self.left) push(self.right, -1*_max)
def __init__(self, file_name): stat = {} file = open(file_name, mode='r') for _ch in file.read(): # print(_ch) ch = _ch if ch in stat.keys(): stat[ch] += 1 else: stat[ch] = 1 file.close() from heapq import heappush as push, heappop as pop forest = [] for ch in sorted(stat.keys()): push(forest, Tree(True, ch, stat[ch])) while len(forest) >= 2: left = pop(forest) right = pop(forest) push(forest, Tree(left=left, right=right, weight=(left.weight + right.weight))) self.t = pop(forest) base = {} def rec(t, tmp): if t.leaf == True: base[t.value] = tmp else: rec(t.left, tmp + ['0']) rec(t.right, tmp + ['1']) rec(self.t, []) self.a = [] buffer = [] file = open(file_name, mode='r') for _ch in file.read(): ch = _ch for b in base[ch]: if len(buffer) == 8: tmp = 0 for i in range(8): tmp *= 2 if buffer[i] == '1': tmp += 1 self.a += [tmp] buffer = [] buffer += [b] self.tail = buffer file.close()
def lastStoneWeight(self, stones: List[int]) -> int: stones = [-1 * x for x in stones] heapify(stones) while True: currLen = len(stones) if currLen > 1: mx1 = -1 * pop(stones) mx2 = -1 * pop(stones) if mx1 != mx2: push(stones, -1 * abs(mx1 - mx2)) elif currLen == 1: return -1 * stones[0] else: return 0
def findKthLargest(self, nums: List[int], k: int) -> int: if not nums: return 0 # declare min heap min_heap = [] # push elements to heap and as soon as size exceeds k(remove smallest element) for i in range(len(nums)): push(min_heap, nums[i]) if len(min_heap) > k: pop(min_heap) return min_heap[0]
def findKthLargest(self, nums: List[int], k: int) -> int: # base case if not nums or not k or k < 0: return None # declare min heap min_heap = [] # push each element to heap and as soon as heap size exceeds k, remove smallest element for num in nums: push(min_heap, num) if len(min_heap) > k: pop(min_heap) return min_heap[0]
def solution(operations): answer = list() for e in operations: a, b = e.split() b = int(b) temp = list() if a == "I": heapq.heappush(answer, b) elif a == "D": if len(answer) == 0: continue else: if b == 1: answer.pop() else: for _ in range(len(answer)): a = heapq.pop(answer) temp.append(a) temp[-1] if len(answer) == 0: return [0, 0] else: anwer most = answer.pop() least = answer.popleft() return [most, least]
def mergeKLists(self, lists: List[ListNode]) -> ListNode: if not lists or len(lists) is 0: return None # custom comparator for list node ListNode.__lt__ = lambda x, y: x.val < y.val # min heap is required to sort in ascending order min_heap = [] # push only head nodes of the lists for head in lists: if head: push(min_heap, head) dummy_head = current = ListNode(-1) while len(min_heap) > 0: min_node = pop(min_heap) current.next = min_node if min_node.next: push(min_heap, min_node.next) current = current.next return dummy_head.next
def searchEM(board, nodesToExpand=10000): startNode = createFunction(board) heap = [] push(heap, (-startNode.score, startNode)) i = 0 while i < nodesToExpand: start = time.time() if len(heap) == 0: break thisNode = pop(heap)[1] if not thisNode.expanded: thisNode.expand() for a in ["L", "R", "D", "U"]: for childNode, _ in thisNode.children[a]: push(heap, (-childNode.score, childNode)) i += 1 # print "time to expand:" , time.time()-start Node.allNodes = {} # print (startNode.bestDir) # pdb.set_trace() startNode.downdate() return board.move(startNode.bestDir)
def mergeKLists(self, lists: List[ListNode]) -> ListNode: # custom less than comparator using a lambda function taking ListNode objects x and y as parameters lessThan = lambda x, y: x.val < y.val ListNode.__lt__ = lessThan # initialize an empty list which acts as min heap minHeapK = [] # create a dummy head and start the cursor from that node dummyHead = ListNode(-1) cursorNode = dummyHead # push into minHeap all head nodes (take care of null checks) for i in range(len(lists)): currHead = lists[i] if (currHead != None): push(minHeapK, currHead) # pop min node and add it to the main linked list, and also push its next node into the min heap (if not null) while (len(minHeapK) > 0): minNode = pop(minHeapK) # pop the min node in the heap cursorNode.next = minNode if (minNode.next != None): # push to the heap only if next node exists push(minHeapK, minNode.next) cursorNode = minNode # update cursor node # return dummy head's next node return dummyHead.next
def kthSmallest(self, matrix: List[List[int]], k: int) -> int: # edge case check if (matrix == None or len(matrix) == 0): return -1 # initializations nRows = len(matrix) nCols = len(matrix[0]) kSmall = [] # first column elements inside the minHeap for r in range(nRows): currObj = ValueCell(matrix[r][0], r, 0) push(kSmall, currObj) currObj = None # remove min from heap k times and insert next min element k times for i in range(k): currObj = pop(kSmall) # remove min element row = currObj.nRows # extract row and col of extracted min element col = currObj.col if (col + 1 < nCols): # if next col is valid => push next col's value nextObj = ValueCell(matrix[row][col + 1], row, col + 1) push(kSmall, nextObj) else: # else min heap's size is reduced by one pass return currObj.val # return kth min object's value
def MST(graph): cost = 0 sub_graph = {list(graph.keys())[0]: graph[list(graph.keys())[0]]} added = {list(graph.keys())[0]} heap = [] counter = {} for vertex in graph.keys(): push(heap, (inf, vertex)) counter[vertex] = inf while (len(sub_graph) != len(graph)): for edges in sub_graph.values(): for edge in edges: if edge[0] not in added: heap.remove((counter[edge[0]], edge[0])) new_val = min(edge[1], counter[edge[0]]) push(heap, (new_val, edge[0])) counter[edge[0]] = new_val vertex = pop(heap) cost += vertex[0] try: sub_graph[vertex[1]] = graph[vertex[1]] except KeyError: pass added.add(vertex[1]) return cost
def func(): t = int(input()) res_for_test_cases = [] for i in range(t): n = int(input()) jobs = [] for j in range(n): jobtemp = input().split() jobs.append([int(i) for i in jobtemp]) totrunningtime = 0 totalmoney = 0 jobs = jobs.sorted(key=sortbydeadline) priorityq = [] heapq.heapify(priorityq) for job in jobs: # heapq.push((job[-1],job[0],job[1])) totrunningtime += jobs[1] if totrunningtime < job[-1]: heapq.push(priorityq, (job[-1], job[0], job[1])) else: highest_a_job = heapq.pop(priorityq) if totrunningtime - highest_a_job[2] < job[-1]: time_to_dec = totrunningtime - job[-1] amount = (highest_a_job[-1] - time_to_dec) / highest_a_job[1] totalmoney += amount heapq.push(priorityq, (highest_a_job[1], highest_a_job[0], highest_a_job[1] - time_to_dec)) print('totalmoney: ', totalmoney) for i in range(t): print(res_for_test_cases[i]) func()
def searchEM(board,nodesToExpand=1000): startNode = createFunction(board) heap = [] push(heap,(-startNode.score,startNode)) i = 0 while i < nodesToExpand: start = time.time() thisNode = pop(heap)[1] if not thisNode.expanded: thisNode.expand() for a in ['L', 'R', 'D', 'U']: for childNode in thisNode.children2[a]: push(heap,(-childNode.score,childNode)) for childNode in thisNode.children4[a]: push(heap,(-childNode.score,childNode)) i += 1 """ else: #print (i) for a in ['L', 'R', 'D', 'U']: for childNode in thisNode.children2[a]: push(heap,(-childNode.score,childNode)) for childNode in thisNode.children4[a]: push(heap,(-childNode.score,childNode)) """ #print "time to expand:" , time.time()-start Node.allNodes = {} #print (startNode.bestDir) #pdb.set_trace() return move(board,startNode.bestDir)
def bathroom(n, k): heap = [] push(heap, -n) for i in range(k - 1): num = -pop(heap) h = num / 2 if num % 2 == 0: push(heap, -h) push(heap, -h + 1) else: push(heap, -h) push(heap, -h) num = -pop(heap) if num % 2 == 0: return num / 2, num / 2 - 1 return num / 2, num / 2
def traverser(self, graph, source, dest): queue = [] start_heuristic = float(graph.node[source]['heuristic']) # Queue item (heuristic, (node, cost, parent)) push(queue, (start_heuristic, (source, 0, None))) while queue: print(queue) currentnode, cost, parent = pop(queue)[1] print(currentnode) # goal check if (currentnode == dest): self.visited[currentnode] = parent self.path = [currentnode] origin = parent while origin is not None: self.path.append(origin) origin = self.visited[origin] self.path.reverse() break if (currentnode not in list(self.visited.keys())): self.visited[currentnode] = parent # check neighbours # Items returns (neighbornode, {dict of edge attributes}) for neighbor, data in graph[currentnode].items(): nheuristic = float(graph.node[neighbor]['heuristic']) ncost = cost + float(data['weight']) # creating list with nodes in the queue queuenodes = [tuple[1][0] for tuple in queue] if (neighbor not in list(self.visited.keys()) and neighbor not in queuenodes): # push to the queue with heuristic, cost ,parent push(queue, (nheuristic, (neighbor, ncost, currentnode)))
def traverse(figure, n, m): dis = [-1 for i in xrange(n * m)] q = [] G = n * m - 1 push(q, (0, 0)) dis[0] = 0 while (len(q) > 0): d, v = pop(q) for u in figure[v]: if (dis[u] > d + 1) or -1 == dis[u]: dis[u] = d + 1 if u == G: return d + 1 push(q, (dis[u], u)) return dis[-1]
def main(): n = int(sys.stdin.readline().strip()) coming_up = defaultdict(int) vs = [] leaves = set(range(1,n+2)) for line in sys.stdin: v = int(line.strip()) coming_up[v] += 1 vs.append(v) if v in leaves: leaves.remove(v) if vs[-1] != n+1: print "Error" return avail = [] for i in leaves: push(avail, i) soln = [] for i in vs: if len(avail) == 0: print "Error" return soln.append(str(pop(avail))) coming_up[i] -= 1 if coming_up[i] == 0: push(avail, i) print "\n".join(soln)
def findKthLargest(self, nums, k): """ :type nums: List[int] :type k: int :rtype: int """ heap = [] for n in nums: if len(heap) < k: push(heap, n) else: if heap[0] < n: pop(heap) push(heap, n) return heap[0]
def kClosest(self, points, K): """ :type points: List[List[int]] :type K: int :rtype: List[List[int]] """ heap = [] for x, y in points[:K]: push(heap, (-x**2 - y**2, x, y)) for x, y in points[K:]: push(heap, (-x**2 - y**2, x, y)) pop(heap) res = [] while len(heap) > 0: x = pop(heap) res.append([x[1], x[2]]) return res
def findClosestElements(self, arr: List[int], k: int, x: int) -> List[int]: if not arr and len(arr) < 1: return heap_list = [] for i in arr: heappush(heap_list, MyObject(abs(x - i), i)) if len(heap_list) > k: pop(heap_list) result = [] while len(heap_list) > 0: x = pop(heap_list).val result.append(x) return sorted(result)
def solution(scoville, K): answer = 0 h = [] for v in scoville: push(h, v) while len(h) > 0: low = pop(h) if low >= K: return answer elif len(h) > 0: push(h, low + pop(h) * 2) answer += 1 return -1
def power_sumDigTerm(n): h = [] for b in range(2, 200): push_next(b, b, 1, h) for k in range(n): p, b, e = pop(h) push_next(p, b, e, h) return p
def minMeetingRooms(self, intervals: List[List[int]]) -> int: if not intervals: return 0 # sort based on start time intervals.sort(key=lambda x: x[0]) room_heap = [] push(room_heap, intervals[0][1]) for i in range(1, len(intervals)): if intervals[i][0] >= room_heap[0]: pop(room_heap) push(room_heap, intervals[i][1]) return len(room_heap)
def Kmost_frequent(word_list, k): if not word_list: return [] n_appear = {word_list[0]: 1} heap = [(1, word_list[0])] for i in range(1, len(word_list)): n_appear[word_list[i]] = n_appear.get(word_list[i], 0) + 1 if len(heap) < k: # If it was in the heap, pop it heapq.pop((n_appear[word_list[i] - 1, word_list[i]])) # add it to the heap heapq.heappush(heap, (n_appear[word_list[i]], word_list[i])) else: # If it was in the heap, pop it heapq.pop((n_appear[word_list[i] - 1, word_list[i]])) if len(heap) == k: heapq.heappop
def AEstrella(origen, funcionParo, g, h): '''Función que implementa el algoritmo A* Parámetros origen: estado desde el que se inicia fucionParo: función que nos indica si llegamos a un estado meta g: función de costo acumulado h: función heuristica return solución o nada ''' historia = [(0, 0)] # solución trivial if funcionParo(origen): return trayectoria(origen), historia # inicializamos al agenda agenda = [] # inicializamos el conjunto de expandidos expandidos = set() # generamos la función f(s) = g(s) + h(s) # f(s) representa el costo total a un nodo # costo acumulado más el costo de la heuristica a ese nodo # esto nos representará la prioridad para cada nodo f = lambda s: g(s) + h(s) # agregamos el primer nodo a la agenda push(agenda, (f(origen), origen)) # mientras existan elementos en la agenda while agenda: historia.append((len(agenda), len(expandidos))) # sacamos un nodo de la agenda nodo = pop(agenda)[1] # pos 1 para obtener el estado de la tupla # lo agregamos al conjunto de expandidos expandidos.add(nodo) # comparamos si este nodo cumple con la función de paro if funcionParo(nodo): return trayectoria(nodo), historia '''Comparamos si el nodo cumple con la función de paro aquí dado que el algoritmo termina cuando el nodo objetivo o estado meta se encuentra en la cabeza de la cola de prioridad, esto ocurrirá cuando el nodo sea el siguiente en salir, por eso se compará afuera del ciclo''' # expandimos el nodo y comparamos a sus hijos for hijo in nodo.expandir(): # agregamos el hijo a la cola de prioridad # siempre y cuando no esté en el conjunto de expandidos if hijo not in expandidos: push(agenda, (f(hijo), hijo)) # si no hay ruta, regresamos un vacio return
def kNearestPoints(points, k): heap = [] result = [] for i in range(len(points)): x, y = points[i] dist = x * x + y * y push(heap, (dist, points[i])) for j in range(k): result.append(pop(heap)[1]) return result
def predict(self, new_X, k, dist_measure): assert k > 0 assert dist_measure in dist_measures heap = [] new_X = (new_X - self.means) / self.stds for i in range(len(self.X)): dist = dist_measures[dist_measure](self.X[i], new_X) push(heap, (dist, i)) labels = list(map(lambda i: self.Y[pop(heap)[1]], range(k))) return np.bincount(labels).argmax()
def Astar(start,goal): q = [start] visited = {} while q: node = pop(q) if node == goal: return node for step in node.steps(): if step not in visited or visited[step] > step: push(q,step) visited[step] = step
def dijkstra(g,raizes): ''' Parametro: g, representando um grafo Retorno: arvore, arvore de caminhos minimos Função: Retorna a SPT (Shortest Path Tree) ou arvore de caminhos minimos do grafo recebido como parametro ''' lista_prioridades = [(Inf,i) for i in range(int(nx.number_of_nodes(g)))] # lista_prioridades transformar em heap heapify(lista_prioridades) # inserir nó 0 (assumindo que o nó 0 é a raiz) com prioridade 0 for i in raizes: push(lista_prioridades, (0, i)) #representação: posterior é o indice e anterior é o valor armazenado anteriores = [None for i in range(int(nx.number_of_nodes(g)))] # cria um dicionário que indica se um vertice v está no heap (se está no heap, ainda não foi processado) inheap = { v: True for v in g.nodes() } # cria um dicionário de pesos pesos = { v: float('inf') for v in g.nodes() } for i in raizes: pesos[i] = 0; while lista_prioridades: no = pop(lista_prioridades) # testa se no ainda não foi removido do heap anteriormente (como não podemos atualizar os pesos, um nó pode repetir) if (inheap[no[1]]): inheap[no[1]] = False # foi retirado do heap pela primeira vez else: continue # já foi retirado do heap antes (repetido) #Seleciona cada vizinho for i in nx.neighbors(g,no[1]): #verifica se vizinho esta na lista de prioridades if (inheap[i]): #verifica se um no é anterior do outro peso = g.get_edge_data(no[1],i)['weight'] + no[0] if peso < pesos[i]: push(lista_prioridades, (peso, i)) anteriores[i] = no[1] pesos[i] = peso arestas = [(i,anteriores[i]) for i in range(len(anteriores))] nos = [] for i in raizes: if (i,None) in arestas: nos.append(i) #Remove arestas que ligam um grafo a None arestas.remove((i,None)) #arestas.pop(0) #Descarta o primeiro pois é a aresta da raiz, que não se liga com ninguém (0,None) g.clear() g.add_edges_from(arestas) #Coloca os nós que ficaram sozinhos g.add_nodes_from(nos) return g
def Prim(g,dic_pesos): ''' Parametro: g, representando um grafo Retorno: arvore, arvore geradora minima Função: Retorna a MST (Minimun Spend Tree) ou arvore geradora minima do grafo recebido como parametro ''' lista_prioridades = [(Inf,i) for i in range(int(nx.number_of_nodes(g)))] # lista_prioridades transformar em heap heapify(lista_prioridades) # inserir nó 0 (assumindo que o nó 0 é a raiz) com prioridade 0 push(lista_prioridades, (0, 0)) #representação: posterior é o indice e anterior é o valor armazenado anteriores = [None for i in range(int(nx.number_of_nodes(g)))] # cria um dicionário que indica se um vertice v está no heap (se está no heap, ainda não foi processado) inheap = { v: True for v in g.nodes() } # cria um dicionário de pesos (evita a necessidade de utilizar a função verifica_vizinho) pesos = { v: float('inf') for v in g.nodes() } pesos[0] = 0; while lista_prioridades: no = pop(lista_prioridades) # testa se no ainda não foi removido do heap anteriormente (como não podemos atualizar os pesos, um nó pode repetir) if (inheap[no[1]]): inheap[no[1]] = False # foi retirado do heap pela primeira vez else: continue # já foi retirado do heap antes (repetido) #Seleciona cada vizinho for i in nx.neighbors(g,no[1]): #verifica se vizinho esta na lista de prioridades if (inheap[i]): #verifica se um no é anterior do outro peso = dic_pesos[(no[1],i)] if peso < pesos[i]: push(lista_prioridades, (peso, i)) anteriores[i] = no[1] pesos[i] = peso arestas = [(i,anteriores[i]) for i in range(len(anteriores))] arestas.pop(0) #Descarta o primeiro pois é a aresta da raiz, que não se liga com ninguém (0,None) g.clear() g.add_edges_from(arestas) return g
def run_medians(numlist): """ Given a list of integers, returns a generator of running medians. The method uses 2 heaps (max heap/min heap) and places streaming numbers in either of the heap depending on their values. The way median is found depends if the heaps are balanced or not. """ itnum = iter(numlist) less, more = [], [] first = next(itnum) yield first second = next(itnum) push(less, - min(first, second)) push(more, max(first, second)) while True: curr = ( more[0] if len(less) < len(more) else - less[0] if len(less) > len(more) else (more[0] - less[0]) / 2.0 ) yield curr it = next(itnum) if it <= curr: push(less, - it) else: push(more, it) small, big = ( (less, more) if len(less) <= len(more) else (more, less) ) if len(big) - len(small) > 1: push(small, - pop(big))
def pop(self):#pop the smallest item key, item = heapq.pop(self.dat); return item;