Top 'K' Elements
A size-k heap replaces full sorting. Push every element; evict when size exceeds k. heap[0] is always the kth largest. O(n log k) — only k elements ever compete.
Sorting for top-k = O(n log n). A size-k heap = O(n log k). When k≪n, this is a massive speedup.
The heap acts as a tournament of k contenders. Every new number challenges the current weakest contender (heap[0] = the minimum). If the challenger wins, the weakest is evicted. After n comparisons, the k survivors are the global top k. The heap minimum is always the kth largest.
The k-Heap Trick
Which heap type depends on which end you're finding.
The min at heap[0] is the smallest of the k largest = kth largest overall. Push new element; if size > k, pop the min (weakest contender). Any new element smaller than heap[0] can't make top k.
heappush(h, num)
if len(h) > k: heappop(h)
# heap[0] = kth largestNegate values for Python max-heap. The max at heap[0] (negated) is the largest of the k smallest = kth smallest overall. Push; if size > k, pop the max (worst contender).
heappush(h, -num)
if len(h) > k: heappop(h)
# -h[0] = kth smallestThe 3-Step Framework
Two-line pattern covers 80% of top-k problems.
For top k largest: use a min-heap. For top k smallest: use a max-heap (negate). For top k by custom key: heap stores (key, value) tuples. Push each element as you scan the input.
for num in nums:
heapq.heappush(heap, num) # or (-num) for max-heap
if len(heap) > k:
heapq.heappop(heap) # evict weakest contenderTop k frequent: Counter(nums) gives frequencies. Then push (freq, num) tuples onto a min-heap of size k. Evict tuples with lowest frequency. Result: the k entries with highest frequency remaining in the heap.
from collections import Counter
count = Counter(nums)
for num, freq in count.items():
heapq.heappush(heap, (freq, num))
if len(heap) > k:
heapq.heappop(heap)Rearrange string, scheduling tasks, connect ropes: use a max-heap (negate in Python). At each step, greedily pop the highest-priority element, use it, and push back with updated state. For cooldown constraints, hold elements in a queue before re-adding.
# Greedy: always pick most frequent
heap = [(-freq, ch) for ch, freq in Counter(s).items()]
heapq.heapify(heap)
while heap:
freq, ch = heapq.heappop(heap) # most frequent
result.append(ch)
# ... handle cooldown / re-pushPattern Recognition
k + largest/smallest/frequent/closest = this pattern.