Unit 1 · Algorithms · Lesson 10 of 24
Heaps, selection and streaming
Builds on
Step 1: Learn the ideas
- Priority-queue interface and its implementations compared
- Binary heap on an array: index arithmetic, sift-up, sift-down
- Linear-time heapify and heap sort
- Top-k with a bounded heap; heap versus quickselect versus buckets
- K-way merge of sorted lists or streams
- Two heaps for running medians
- Lazy deletion and stale entries
- Tie-breaking and decrease-key in library heaps
- Heaps in schedulers and event simulation
Why it matters
Whenever you repeatedly need the smallest or largest item while items keep arriving, a heap is the natural structure: schedulers pick the next job, Dijkstra's algorithm picks the closest unsettled node, a merger picks the smallest head among k sorted runs, and monitoring code keeps the slowest requests. Interviews use heaps for selection and streaming problems, and the follow-up questions test whether you know the alternatives.
Core ideas
Structure. A binary heap is a complete binary tree stored in an array: with 0-based index i, the children are at 2i + 1 and 2i + 2 and the parent at (i − 1) // 2. The heap property (every parent is no larger than its children, for a min-heap) puts the minimum at the root. Insert appends and sifts up; extract moves the last element to the root and sifts down. Both are O(log n) because the height is ⌊log₂ n⌋; peeking is O(1).
Build in O(n). Sifting down every internal node, from the last one back to the root, costs O(n) rather than O(n log n): most nodes sit near the bottom and move only a short distance, and the heights of all nodes in a complete tree sum to O(n). Heap sort is a build plus n extractions: O(n log n) worst case, in place, not stable.
Pattern: Heap selection / top-k. To keep the k largest items of a stream, hold a min-heap of size k. Its root is the smallest of the current top k, so a new item enters only if it beats the root. That costs O(n log k) time and O(k) space and works on streams too large to store. Alternatives: sorting (O(n log n), simplest), quickselect (O(n) expected but O(n²) worst case, needs all data in memory and reorders it), or bucket counting when keys are small integers (Top K Frequent Elements by frequency buckets is O(n)).
K-way merge. Push the head of each sorted list as (value, list_id, position), then repeatedly pop the minimum and push the next element from the same list. With N items across k lists this is O(N log k). The same frontier idea finds the k smallest pair sums without generating every pair.
Pattern: Two heaps / streaming statistics. For a running median, keep a max-heap for the lower half and a min-heap for the upper half, sizes equal or the lower half one larger. Insert into one side, move its top across if the halves are out of order, then rebalance sizes; the median is the lower top or the mean of both tops. Each insertion is O(log n) and each query O(1). A sliding-window median also needs removals, which library heaps do not support efficiently: record outgoing values as pending deletions, discard them when they surface at a top, and track each heap's effective size.
Library behavior. Python heapq and Java PriorityQueue are min-heaps; C++ std::priority_queue is a max-heap; JavaScript has no built-in heap. For max-heaps over numbers, negate keys or pass a reversed comparator. When payloads are not comparable (list nodes, objects), add a tie-breaking counter so equal priorities never compare payloads. Most library heaps lack decrease-key: push a new entry and skip stale ones when popped. Go's container/heap provides Fix if you track each item's index.
Common misconceptions
- "For the k largest, use a max-heap of everything." That costs O(n) space and O(n + k log n) time; a size-k min-heap uses O(k) space and also works on streams.
- "Building a heap is O(n log n)." Bottom-up heapify is O(n); only n separate insertions cost O(n log n).
- "A heap is a sorted array." Only the root is guaranteed to be the extreme; iterating the underlying array does not give sorted order.
- "Quickselect always beats a heap." Quickselect is O(n) only in expectation, needs all data in memory and mutates it; a heap streams with a guaranteed bound.
- "Changing a priority is cheap." Library heaps cannot find an item quickly; use lazy deletion or an indexed heap that you implement.
How to approach it
When a problem says k largest, k closest, next earliest or median so far, consider a heap and say which kind and why, especially the counterintuitive min-heap for the k largest. State the heap's size bound (k, the number of lists, or n), because it sets the log factor. Interviewers typically ask for an alternative (sorting, quickselect, buckets), the space cost, and how the solution changes for a stream that never ends.
Suggested order
- 1Read MIT 6.006 Lecture 8 (Binary Heaps) for the array representation, insert, delete-max, linear build and in-place heap sort.
- 2Read MIT 6.006 Recitation 8 and the algs4 Priority Queues section (2.4) for implementations to compare with your own, including the index priority queue.
- 3Implement a binary min-heap from scratch (push, pop, heapify) and test it against your language’s library heap on random inputs.
- 4Solve Last Stone Weight and Kth Largest Element in a Stream to practice max-heap and size-k min-heap behavior in your language.
- 5Solve Kth Largest Element in an Array three ways (sort, size-k heap, quickselect), then Top K Frequent Elements with a heap and with buckets.
- 6Solve K Closest Points to Origin, Merge k Sorted Lists and Find K Pairs with Smallest Sums, adding tie-breakers where payloads are not comparable.
- 7Solve Find Median from Data Stream with two heaps, then Sliding Window Median with lazy deletion as the harder review.
Step 2: Check off what you can do
Tap each one you can genuinely do or explain. Each earns 10 XP.
Step 3: Go deeper
MIT 6.006 Introduction to Algorithms (Spring 2020)Start here
MIT OpenCourseWareSection: Lecture 8: Binary Heaps
Array-based complete trees, insert and delete-max, linear-time build and in-place heap sort.
Open(opens in a new tab)Link responded, 5 Oct 2026MIT 6.006 Introduction to Algorithms (Spring 2020)
MIT OpenCourseWareSection: Recitation 8
Python priority queues backed by an array, a sorted array and a binary heap, and the sorting algorithm each one yields.
Open(opens in a new tab)Link responded, 5 Oct 2026Algorithms, 4th Edition booksite: sorting, searching and trie sections
Princeton UniversitySection: 2.4 Priority Queues
Heap implementation with sink and swim, heapsort, a multiway merge client and index priority queues for priority changes.
Open(opens in a new tab)Link responded, 5 Oct 2026Python documentation: costs of built-in types and the container modules
Python Software Foundation (docs.python.org)Section: heapq: Priority Queue Implementation Notes
Tie-breaking with entry counts and marking entries as removed (lazy deletion); the page also documents the max-heap functions added in Python 3.14.
Open(opens in a new tab)Link responded, 5 Oct 2026cppreference: C++ containers library, priority_queue, sort and lower_bound
cppreference.comSection: std::priority_queue
C++ default max-heap order and how a comparator such as std::greater produces a min-heap.
Open(opens in a new tab)Link responded, 5 Oct 2026
Step 4: Practice
Before each problem, say which heap (min or max), what it holds and its maximum size, since that sets the log factor. Implement a heap yourself once, then use the library. Kth Largest Element in an Array is the place to compare heap, sort and quickselect. Find Median from Data Stream and Sliding Window Median are the two-heap checks; the second requires lazy deletion.
- Last Stone WeightLeetCode(opens in a new tab)Not attemptedLeetCode
- Kth Largest Element in a StreamLeetCode(opens in a new tab)Not attemptedLeetCode
- Kth Largest Element in an ArrayLeetCode(opens in a new tab)Not attemptedLeetCode
- Top K Frequent ElementsLeetCode(opens in a new tab)Not attemptedLeetCode
- K Closest Points to OriginLeetCode(opens in a new tab)Not attemptedLeetCode
- Merge k Sorted ListsLeetCode(opens in a new tab)Not attemptedLeetCode
- Task SchedulerLeetCode(opens in a new tab)Not attemptedLeetCode
- Find K Pairs with Smallest SumsLeetCode(opens in a new tab)Not attemptedLeetCode
- Find Median from Data StreamLeetCode(opens in a new tab)Not attemptedLeetCode
- Sliding Window MedianLeetCode(opens in a new tab)Not attemptedLeetCode
- Design TwitterLeetCode(opens in a new tab)Not attemptedLeetCode
Record attempts on each problem’s page (+15 XP, +10 more when solved on your own).
Step 5: Test yourself
Answer each one out loud or on paper before you finish the lesson.
- Question 1Why do you use a min-heap to keep the k largest elements?
- Question 2Why is bottom-up heapify O(n)?
- Question 3What invariant do the two heaps maintain for a running median?
- Question 4How do you get max-heap behavior from your language’s heap, and how do you break ties between non-comparable payloads?
- Question 5How do you remove an arbitrary element or change a priority when there is no decrease-key?
- Question 6What does merging k sorted lists of total length N cost in time and space?
You’re done when you can
- Implement a binary heap with push, pop and linear-time heapify from memory, passing randomized tests against the library heap.
- Solve two unseen top-k or k-way-merge problems in under 20 minutes each with correct bounds.
- Solve Find Median from Data Stream in under 25 minutes and explain the balancing invariant.
- Explain when quickselect, bucket counting or sorting is preferable to a heap.
Finish the lesson
Unlocks next: Shortest paths and their assumptions, Pattern recognition and mixed practice


