Heaps & Priority Queues — Master Recap & Cheatsheet

Sanjeev SharmaSanjeev Sharma
5 min read

Advertisement

Heaps Section Complete — 46 Problems (421–466)

7 Core Heap Patterns

Pattern 1 — Top K with Fixed-Size Heap

# K largest: use min-heap of size K
heap = []
for n in nums:
    heapq.heappush(heap, n)
    if len(heap) > k:
        heapq.heappop(heap)
return heap  # k largest elements, heap[0] = kth largest

# K smallest: use max-heap of size K (negate values)

Pattern 2 — Two Heaps (Dynamic Median)

lo, hi = [], []  # lo=max-heap (negate), hi=min-heap
def add(num):
    heapq.heappush(lo, -num)
    heapq.heappush(hi, -heapq.heappop(lo))
    if len(lo) < len(hi):
        heapq.heappush(lo, -heapq.heappop(hi))

def median():
    if len(lo) > len(hi): return -lo[0]
    return (-lo[0] + hi[0]) / 2

Pattern 3 — K-way Merge

# Merge k sorted lists/streams
heap = [(lst[0], i, 0) for i, lst in enumerate(lists) if lst]
heapq.heapify(heap)
while heap:
    val, i, j = heapq.heappop(heap)
    result.append(val)
    if j + 1 < len(lists[i]):
        heapq.heappush(heap, (lists[i][j+1], i, j+1))

Pattern 4 — Greedy + Max-Heap (Scheduling)

# Task scheduler, reorganize string, course schedule III
# Key: sort by constraint, use max-heap for greedy choice
import heapq
heap = [-freq for freq in frequencies]  # max-heap
heapq.heapify(heap)
while heap:
    top = -heapq.heappop(heap)
    # ... greedy decision

Pattern 5 — Retroactive Greedy (Min-Heap)

# Furthest building, minimum refueling stops
# Commit greedily, fix up later with heap
heap = []  # store ladder-climbs or gas stations
for step in steps:
    heap.push(step)
    if over_budget:
        use_worst = heap.pop()  # replace with bricks/fuel
        adjust_budget

Pattern 6 — Multi-pointer DP (Ugly Numbers)

# K sorted streams, pick minimum each step
ptrs = [0] * k
ugly = [1]
for _ in range(n - 1):
    next_val = min(ugly[ptrs[j]] * primes[j] for j in range(k))
    ugly.append(next_val)
    for j in range(k):
        if ugly[ptrs[j]] * primes[j] == next_val:
            ptrs[j] += 1

Pattern 7 — Two-Heap with Lazy Deletion

# Sliding window median, dynamic median with deletions
trash = defaultdict(int)
def remove(val, is_lo):
    trash[val] += 1
    # size adjustments
    # on access: skip trashed elements at heap tops

Problem Index

#TitlePatternDifficulty
421Kth Largest in StreamTop KEasy
422Last Stone WeightMax-heap simEasy
423Relative RanksSortEasy
424K Closest ElementsBinary searchMedium
425Kth Largest ElementQuickselect/heapMedium
426Top K FrequentBucket/heapMedium
427Sort Characters by FreqFreq+heapMedium
428K Closest PointsTop KMedium
429Task SchedulerMath/greedyMedium
430Reorganize StringGreedy+heapMedium
431Find Median from StreamTwo heapsHard
432Sliding Window MedianTwo heaps+lazyHard
433Merge K Sorted ListsK-way mergeHard
434Kth Smallest in MatrixHeap/BSMedium
435K Pairs Smallest SumsK-way mergeMedium
436Ugly Number IIMulti-ptr DPMedium
437Course Schedule IIIGreedy+heapHard
438Meeting Rooms IISchedulingMedium
439Min Cost Connect SticksHuffmanMedium
440IPOTwo heapsHard
441Car PoolingDiff arrayMedium
442Furthest BuildingRetroactive greedyMedium
443Process Tasks ServersTwo heapsMedium
444Trapping Rain Water IIBFS+min-heapHard
445Swim in Rising WaterDijkstraHard
446Smallest Range K ListsK-way mergeHard
447Super Ugly NumberMulti-ptrMedium
448Min Refueling StopsRetroactive greedyHard
449Design TwitterK-way mergeMedium
450Ugly Number IIIBinary search + IEMedium
451Max Performance TeamGreedy+heapHard
452Longest Happy StringGreedy+heapMedium
453Max Frequency StackFreq bucketsHard
454Minimize DeviationGreedy+heapHard

Complexity Summary

OperationMin-Heap/Max-Heap
Build (heapify)O(n)
PushO(log n)
PopO(log n)
Peek/topO(1)
SearchO(n)
Delete arbitraryO(n) or O(log n) with lazy

Key Rules

  1. Top K largest: min-heap of size k (evict smallest)
  2. Top K smallest: max-heap of size k (evict largest)
  3. Median: two heaps (lo max-heap, hi min-heap), sizes differ by ≤ 1
  4. Merge K sorted: min-heap with (val, list_idx, elem_idx)
  5. Greedy scheduling: sort by constraint (deadline, start), heap for best choice
  6. Python max-heap: negate values (heapq is min by default)
  7. Lazy deletion: when you can't efficiently remove from middle — use tombstone map

Python Max-Heap Patterns

# Max-heap for integers
heap = [-n for n in nums]
heapq.heapify(heap)
max_val = -heapq.heappop(heap)

# Max-heap for tuples
heapq.heappush(heap, (-priority, item))
priority, item = -val, item = heapq.heappop(heap)

# heapreplace: more efficient pop+push when heap non-empty
heapq.heapreplace(heap, new_val)  # pops min, pushes new_val

Advertisement

Sanjeev Sharma

Written by

Sanjeev Sharma

Full Stack Engineer · E-mopro