def heappushpop_max(heap, item): """Fast version of a heappush followed by a heappop.""" if heap and heap[0] > item: # if item >= heap[0], it will be popped immediately after pushed item, heap[0] = heap[0], item _siftup_max(heap, 0) return item
def running_median(lst): # O(nlogn) time, O(n) space import heapq # maintain left side (max heap), median, right side (min heap) max_heap, min_heap = [], [] for num in lst: if max_heap and max_heap[0] > num: max_heap.append(num) heapq._siftup_max(max_heap, len(max_heap) - 1) else: heapq.heappush(min_heap, num) lmax, lmin = len(max_heap), len(min_heap) if lmax > lmin + 1: heapq.heappush(min_heap, heapq._heappop_max(max_heap)) elif lmin > lmax + 1: max_heap.append(heapq.heappop(min_heap)) heapq._siftup_max(max_heap, lmax - 1) lmax, lmin = len(max_heap), len(min_heap) if lmax == lmin: print((max_heap[0] + min_heap[0]) / 2) elif lmax - lmin == 1: print(max_heap[0]) else: # lmin - lmax == 1 print(min_heap[0])
def _balance(self): while len(self.heap_high) - len(self.heap_low) > 1: self.heap_low.append(heapq.heappop(self.heap_high)) heapq._siftdown_max(self.heap_low, 0, len(self.heap_low) - 1) while len(self.heap_low) - len(self.heap_high) > 1: heapq.heappush(self.heap_high, heapq.heappop(self.heap_low)) heapq._siftup_max(self.heap_low, 0)
def _heappop_max(heap): lastelt = heap.pop() if heap: returnitem = heap[0] heap[0] = lastelt heapq._siftup_max(heap, 0) return returnitem return lastelt
def MinimizeSum(heap, n, k): heapq._heapify_max(heap) for i in range(k): if heap[0] == 1: break heap[0] = heap[0] >> 1 heapq._siftup_max(heap, 0) return sum(heap)
def pop(self): lastelt = self._heap.pop( ) # raises appropriate IndexError if heap is empty if self._heap: returnitem = self._heap[0] self._heap[0] = lastelt _siftup_max(self._heap, 0) return returnitem return lastelt
def mheappop(heap): lastegt = heap.pop() if heap: returnitem = heap[0] heap[0] = lastegt _siftup_max(heap, 0) else: returnitem = lastegt return returnitem
def max_heappop(heap): """Maxheap version of a heappop.""" lastelt = heap.pop() # raises appropriate IndexError if heap is empty if heap: returnitem = heap[0] heap[0] = lastelt hq._siftup_max(heap, 0) return returnitem return lastelt
def heappop_max(heap): last = heap.pop() if heap: return_item = heap[0] heap[0] = last _siftup_max(heap, 0) else: return_item = last return return_item
def _heappop_max(self, heap): """Maxheap version of a heappop.""" lastelt = heap.pop() if heap: returnitem = heap[0] heap[0] = lastelt heapq._siftup_max(heap, 0) return returnitem return lastelt
def _heappop_max(heap): """Maxheap version of a heappop.""" lastelt = heap.pop() # raises appropriate IndexError if heap is empty if heap: returnitem = heap[0] heap[0] = lastelt heapq._siftup_max(heap, 0) return returnitem return lastelt
def maxheappop(heap): """Pop the largest item off the heap, maintaining the heap invariant.""" lastelt = heap.pop() # raises appropriate IndexError if heap is empty if heap: returnitem = heap[0] heap[0] = lastelt heapq._siftup_max(heap, 0) else: returnitem = lastelt return returnitem
def next(self): if not self.heap: raise StopIteration elif len(self.heap) == 1: return self.heap.pop() last_item = self.heap.pop() result = self.heap[0] self.heap[0] = last_item heapq._siftup_max(self.heap, 0) return result
def maxheapreplace(heap, item): """Pop and return the current largest value, and add the new item. This is more efficient than heappop() followed by heappush(), and can be more appropriate when using a fixed-size heap. Note that the value returned may be smaller than item! That constrains reasonable uses of this routine unless written as part of a conditional replacement: if item > heap[0]: item = heapreplace(heap, item) """ returnitem = heap[0] # raises appropriate IndexError if heap is empty heap[0] = item heapq._siftup_max(heap, 0) return returnitem
def getLeastNumbers(self, arr, k): import heapq res = heapq.nsmallest(k, arr) return res import heapq # import _heapq as heapq l = len(arr) k = min(l, k) if k == 0: return [] res = deepcopy(arr[:k]) heapq._heapify_max(res) for i in range(k, l): if arr[i] < res[0]: res[0] = arr[i] heapq._siftup_max(res, 0) return res
def que_method(input_nums, k): """ 建立k的最大堆:记录当前最小的k个数 单次调整堆的时间复杂度:log(k),总和时间复杂度:nlog(k) """ out_nums = copy.deepcopy(input_nums) import heapq start_time = time.time() k_que = out_nums[:k] heapq._heapify_max(k_que) for num in out_nums[k:]: # 如果num小于当前的堆顶,则替换堆顶,并调整最大堆 if num < k_que[0]: k_que[0] = num heapq._siftup_max(k_que, 0) out_num = k_que[0] end_time = time.time() print("que_methold:", end_time - start_time) return out_num
def remove(smallMaxHeap, bigMinHeap, x): if not smallMaxHeap and not bigMinHeap: print("Wrong!") return False if x <= smallMaxHeap[0]: try: index = smallMaxHeap.index(x) except: print("Wrong!") return False if index == (len(smallMaxHeap) - 1): smallMaxHeap.pop() else: smallMaxHeap[index] = smallMaxHeap.pop() _siftup_max(smallMaxHeap, index) elif x >= smallMaxHeap[0]: try: index = bigMinHeap.index(x) except: print("Wrong!") return False if index == (len(bigMinHeap) - 1): bigMinHeap.pop() else: bigMinHeap[index] = bigMinHeap.pop() _siftup(bigMinHeap, index) # rebalance everything if len(smallMaxHeap) > (len(bigMinHeap) + 1): item = _heappop_max(smallMaxHeap) heappush(bigMinHeap, item) elif len(bigMinHeap) > (len(smallMaxHeap) + 1): item = heappop(bigMinHeap) _heappushMax(smallMaxHeap, item) return True
def approx_median_heap(arr, sigma): min_heap = [arr.pop(0)] min_l = 1 max_heap = [arr.pop(0)] max_l = 1 med = None while len(arr) > 0: # randomly samply item from arr elem = arr.pop(random.randint(0, len(arr) - 1)) # append to shorter heap if len(min_heap) > len(max_heap): max_heap.insert(0, elem) heapq._siftup_max(max_heap, 0) max_l += 1 else: heapq.heappush(min_heap, elem) min_l += 1 # check if heap elems need to be swapped while min_heap[0] < max_heap[0]: temp1 = max_heap[0] temp2 = min_heap[0] heapq._heappushpop_max(max_heap, temp2) heapq.heappushpop(min_heap, temp1) # calculate median if min_l > max_l: med = min_l[0] elif max_l > min_l: med = max_l[0] else: med = (min_l[0] + max_l[0]) / 2 # check if certainly within sigma radius = len(arr) # unchecked vars # how do i check when heaps aren't fully sorted???? return (min_heap, max_heap)
def reorganizeString(self, S: str) -> str: char_count = {} for s in S: if s in char_count: char_count[s][0]+=1 else: char_count[s] = [1,s] max_s = list(char_count.values()) heapq._heapify_max(max_s) max_char = heapq._heappop_max(max_s) ans = "" for _ in range(len(S)-1): ans += max_char[1] if len(max_s) ==0: return "" if max_char[0] > 1: mid = max_s[0] max_char[0]-=1 max_s[0],max_char = max_char,mid heapq._siftup_max(max_s,0) else : max_char = heapq._heappop_max(max_s) return ans+max_char[1]
def kClosest(self, points: List[List[int]], K: int) -> List[List[int]]: kclosest = [] kclosest.append((self.dist(points[0]), [points[0][0], points[0][1]])) for k in range(1, len(points)): if len(kclosest) < K: d = self.dist(points[k]) kclosest.append( (self.dist(points[k]), [points[k][0], points[k][1]])) heapq._siftup_max(kclosest, -1) elif abs(points[k][0]) < abs(kclosest[0][1][0]) and abs( points[k][1]) < abs(kclosest[0][1][1]): d = self.dist(points[k]) heapq._heappop_max(kclosest) kclosest.append( (self.dist(points[k]), [points[k][0], points[k][1]])) heapq._siftup_max(kclosest, -1) elif abs(points[k][0]) >= abs(kclosest[0][1][0]) and abs( points[k][1]) >= abs(kclosest[0][1][1]): continue else: d = self.dist(points[k]) if d < kclosest[0][0]: heapq._heappop_max(kclosest) kclosest.append( (self.dist(points[k]), [points[k][0], points[k][1]])) heapq._siftup_max(kclosest, -1) res = [] for p in kclosest: res.append(p[1]) return res
def heapreplace_max(arr, item): ret, arr[0] = arr[0], item heapq._siftup_max(arr, 0) return ret
print "rightHeap is: " print rightHeap print "leftHeap is: " print leftHeap if (len(rightHeap) > len(leftHeap)): print "===RIGHT LONGER===" print "n is: " + str(n) print "curMedian is: " + str(curMedian) if(n >= curMedian): heapq.heappush(leftHeap, curMedian) heapq._heapPy curMedian = heapq.heappop(rightHeap) #curMedian = rightHeap[0] heapq.heappush(rightHeap, n) else: heapq._siftup_max(leftHeap, 0) elif (len(leftHeap) > len(rightHeap)): print "===LEFT LONGER===" print "n is: " + str(n) print "curMedian is: " + str(curMedian) if(n <= curMedian): heapq.heappush(rightHeap, curMedian) curMedian = heapq.heappop(leftHeap) #curMedian = left[0] heapq.heappush(leftHeap, n) else: heapq.heappush(rightHeap,n) else: print "===EQUAL || < 1 Diff LENGTH==="
def median(_add=None, _remove=None): result = None max_l = len(max_heap) min_l = len(min_heap) if _add: if not min_l: heapq.heappush(min_heap, _add) elif max_l > min_l: if _add < max_heap[0]: temp = max_heap[0] heapq._heapreplace_max(max_heap, _add) heapq.heappush(min_heap, temp) else: heapq.heappush(min_heap, _add) elif max_l < min_l: if _add > min_heap[0]: temp = min_heap[0] heapq.heapreplace(min_heap, _add) max_heap.append(temp) heapq._siftdown_max(max_heap, 0, max_l) else: max_heap.append(_add) heapq._siftdown_max(max_heap, 0, max_l) else: if _add > min_heap[0]: heapq.heappush(min_heap, _add) else: max_heap.append(_add) heapq._siftdown_max(max_heap, 0, max_l) max_l = len(max_heap) min_l = len(min_heap) if _remove: if min_heap and _remove >= min_heap[0]: indx = min_heap.index(_remove) min_heap[indx] = min_heap[-1] min_heap.pop() if indx < len(min_heap): heapq._siftup(min_heap, indx) heapq._siftdown(min_heap, 0, indx) elif max_heap and _remove <= max_heap[0]: indx = max_heap.index(_remove) max_heap[indx] = max_heap[-1] max_heap.pop() if indx < len(max_heap): heapq._siftup_max(max_heap, indx) heapq._siftdown_max(max_heap, 0, indx) max_l = len(max_heap) min_l = len(min_heap) if max_l - min_l >= 2: temp = max_heap[0] heapq._heappop_max(max_heap) heapq.heappush(min_heap, temp) elif min_l - max_l >= 2: temp = min_heap[0] heapq.heappop(min_heap) max_heap.append(temp) heapq._siftdown_max(max_heap, 0, max_l) min_l = len(min_heap) max_l = len(max_heap) if min_l == max_l: result = (max_heap[0] + min_heap[0]) / 2 # print(f'debug: max_heap[0]: {max_heap[0]} min_heap[0]:{min_heap[0]}') elif min_l > max_l: result = min_heap[0] else: result = max_heap[0] return result
def maxheappushpop(heap, item): """Fast version of a heappush followed by a heappop.""" if heap and heapq.cmp_lt(item, heap[0]): item, heap[0] = heap[0], item heapq._siftup_max(heap, 0) return item
def update_event(self, inp=-1): self.set_output_val(0, heapq._siftup_max(self.input(0), self.input(1)))
def replace_elem(self, heap_arr_index): assert heap_arr_index < len(self.heap), 'input arr-index out of bounds' replaced_elem = self.heap[heap_arr_index] self.heap[heap_arr_index] = self.heap[-1] heapq._siftup_max(self.heap, 0) return replaced_elem
def _heappushpop_max(heap, item): if heap and item < heap[0]: item, heap[0] = heap[0], item heapq._siftup_max(heap, 0) return item
def _heapreplace_max(heap, item): """Maxheap version of a heappop followed by a heappush.""" returnitem = heap[0] # raises appropriate IndexError if heap is empty heap[0] = item _siftup_max(heap, 0) return returnitem