Recognize the Pattern
- Maintain the best K candidates from a stream.
- Repeatedly choose the earliest ending interval or smallest list head.
- Explore candidates by score rather than arrival order.
Core Invariant
Every parent outranks its children under the comparator. The root is the best candidate; siblings need not be sorted.
Important Boundary
For the K largest values, keep the smallest retained value at the root. Mutating an item's priority in place does not repair the heap.
The root is best, the rest need not be sorted
For a zero-indexed array, parent(i) is floor((i-1)/2), with children 2i+1 and 2i+2. A comparator returning a negative number means its first argument has higher priority.
Insertion appends a value and moves it upward until its parent is no worse. Extraction replaces the root with the last value and moves it downward toward the better child. A complete binary tree has logarithmic height, bounding both repairs.
| Task | Comparator | What the root means |
|---|---|---|
| Smallest number first | (a, b) => a - b | Minimum |
| Largest number first | (a, b) => b - a | Maximum |
| Earliest event first | (a, b) => a.time - b.time | Earliest timestamp |
| Keep K largest numbers | Min heap of size K | Worst retained candidate |
Heap, sorting, or selection?
| Requirement | Prefer | Trade-off |
|---|---|---|
| All values in order once | Comparison sorting | A typical O(N log N) baseline; a heap does not eliminate the full ordering cost. |
| Keep K largest values as items arrive | Min heap of at most K retained items | O(N log(K + 1)) time; retained candidates are not fully sorted. |
| One rank in a static mutable array | Randomized quickselect | Expected O(N), worst-case O(N squared); partitions mutate the input. |
| Repeated next-best choice with new candidates | Priority queue | Pay logarithmic repair costs instead of sorting the frontier again. |
A comparator-driven binary heap
This template uses built-in JavaScript only. Empty peek and pop return undefined. Equal priorities may be returned in any order; add a secondary key if your problem requires deterministic ties.
Template Assumptions
- A negative comparator result means the first item has higher priority; the default is a numeric min-heap.
- peek and pop return undefined for an empty heap; priorities remain stable while queued.
JavaScript Template
Trace top-K by protecting the worst retained item
In Merge K Sorted Lists, store only the head of each nonempty list. After extracting one node, insert that node's successor. The frontier has at most K entries; storing every node up front discards the useful structure of the input.
- For K = 3, insert 3, 2, and 1 into a min heap. The root is 1.
- Insert 5. The heap now has four candidates, so pop its minimum, 1.
- Insert 6 and pop 2. Insert 4 and pop 3.
- The retained values are 4, 5, and 6. The root, 4, is the third largest.
Step-by-Step: Min-heap sift-up and sift-down
- Heap array
- [1,3,2,7,5]
- Ordering
- Valid min heap
Start with a valid min heap
Every parent is no greater than either child. The array need not be sorted.
Costs depend on frontier size
- peek is O(1). push and pop are O(log H), where H is the current heap size. Storage is O(H).
- The displayed constructor starts empty. Building by N repeated pushes is O(N log N) worst case; bottom-up heap construction is a separate O(N) algorithm.
- Keeping K candidates over N values takes O(N log(K + 1)) time and O(K) space. For K=1, the work is still linear.
- Merging N total list nodes with at most K active heads takes O(N log(K + 1)) time and O(K) heap space.
- For a static array that needs a full sorted result once, sorting can be simpler. A heap is not automatically the best choice for every top-K question.
Do not silently change the priority
- Re-sorting the entire candidate array after each insertion loses the heap's update bound.
- When sinking, compare both children and swap with the better one, not always the left child.
- Changing an object's priority after insertion can break the invariant. Reinsert a new immutable candidate or use a data structure supporting priority updates.
- A heap does not make a graph algorithm correct by itself. Define the score, relaxation rule, and stale-entry policy separately.
- For time-based frontend work, a heap orders events but does not implement timers, cancellation, or browser scheduling.
Mistakes and Counterexamples
Use a max heap and discard its root to keep the K largest values.
Counterexample: For K=2 and values [4,5,6], discarding the maximum removes 6 and retains [4,5], the wrong candidates.
Correction: Keep a min heap: its root is the worst retained candidate, so overflow discards 4 and keeps [5,6].
Always swap with the left child when sinking.
Counterexample: The temporary min-heap array [8,3,2] must swap 8 with 2. Swapping with 3 leaves the root larger than its right child.
Correction: Compare both existing children and choose the one with higher priority.
Mutate an item's priority without repairing the heap.
Counterexample: Two events have priorities 2 and 5. Changing the second to 1 in place leaves the old root 2 at the front.
Correction: Use supported priority updates, or push a new candidate and invalidate stale entries by identity/version. Do not mutate a retained entry in place.
Last-Minute Recap
- State the comparator direction explicitly.
- The root is the best candidate, not proof that the array is sorted.
- Analyze the maximum frontier size, not only total input size.
Explain It in an Interview
- Why does top-K use a min-heap when looking for the largest values?
- When would sorting or quickselect be preferable?
- What must happen after changing a queued candidate's priority?
Ready to Apply This Pattern?
Before coding, explain why this pattern fits and what must stay true at each step. Start with an easier problem, then test that reasoning on a harder variation.
Ordered from Easy to Hard. Premium access requirements still apply.
- 1.Kth Largest Element in an ArrayKeep the worst of the retained K candidates at the root.Medium
- 2.Top K Frequent Elements - Trending ItemsDistinguish frequency counting from selecting the K largest frequencies.Medium
- 3.Meeting Rooms II - Min HeapMaintain active end times rather than sorting the whole frontier on each update.Medium
- 4.Employee Free TimeUse sorted schedules to bound the frontier; compare a heap with flatten-and-sort.Medium
- 5.Notification Scheduler with Cooldown PeriodsPrioritize available task frequencies while keeping cooldown eligibility separate from heap order.Medium
- 6.Merge K Sorted ListsKeep one head per nonempty list and replenish only the extracted list.Hard
- 7.Find Median from Data Stream - Live AnalyticsMaintain two heap partitions and their size/order invariants.Hard
- 8.Path With Maximum Minimum ValuePrioritize bottleneck scores and justify the relaxation or threshold rule.Hard