When an interview asks for the "top‑k" elements you are being asked to return the k largest or smallest items from a collection. The pattern is useful because a full sort ( O(n log n) ) is often overkill when k is much smaller than n. By using a min‑heap of size k or a quick‑select partition you can achieve O(n log k) or O(n) average time, respectively, while keeping memory linear in k.
Spotting the Top‑k Signal
Interview problems rarely say "use a heap" outright. Look for phrasing that limits the output to a count:
- "Return the first k largest numbers."
- "Find the k most frequent words."
- "Give the k students with the highest GPA."
- "Return the k closest points to the origin."
If the requirement mentions a fixed k or a small k relative to the input size, you are likely in the top‑k domain. When the problem also asks for order (e.g., sorted descending), you can still use a heap and sort the final k items, which adds only O(k log k) overhead.
A Worked Example
Problem: Given an array of integers, return the three largest distinct values.
Approach: A min‑heap of capacity 3 keeps the current top three. For each number:
- If the heap has fewer than 3 items, push the number.
- Else if the number is greater than the smallest (heap[0]), pop the smallest and push the new number.
- After processing, the heap contains the answer; convert to a sorted list if needed.
Python code:
import heapq
def top_three(nums):
heap = []
for x in nums:
if x in heap:
continue # keep distinct values
if len(heap) < 3:
heapq.heappush(heap, x)
elif x > heap[0]:
heapq.heapreplace(heap, x)
return sorted(heap, reverse=True)
Complexity: Each push/pop is O(log k) = O(log 3) ≈ O(1). Over n elements the total time is O(n). The heap stores at most 3 items, so space is O(k).
Common Pitfalls
| Pitfall | Why it hurts | Fix |
|---|---|---|
| Using a max‑heap and then popping k times | Each pop is O(log n) instead of O(log k) | Use a min‑heap of size k or quick‑select. |
| Forgetting distinctness when required | You may return duplicate values and fail hidden tests | Keep a set alongside the heap or check before insertion. |
| Sorting the whole array first | Turns the solution into O(n log n) and defeats the purpose | Only sort the final k elements if order matters. |
| Assuming k is constant | Some problems vary k per test case; hard‑coding can break scalability | Read k from input and allocate the heap dynamically. |
Five Practice Problems
- K Largest Sum Sub‑array – Given an integer array, find the k sub‑arrays with the highest sums. Hint: Compute prefix sums, then use a max‑heap of candidate intervals.
- Top K Frequent Words – Return the k most common words from a paragraph. Hint: Build a frequency map, then push (frequency, word) into a min‑heap of size k.
- K Closest Points to Origin – From a list of (x, y) points, return the k nearest to (0,0). Hint: Store squared distance in a max‑heap of size k to discard farther points early.
- K Smallest Pairs Sum – Given two sorted arrays, produce the k pairs with the smallest sum. Hint: Use a min‑heap seeded with the first element of each array and expand neighbours lazily.
- K Most Frequent Elements in a Stream – Elements arrive one by one; after each insertion, output the current k most frequent. Hint: Maintain a frequency map and a min‑heap; when a frequency changes, adjust the heap accordingly (or use a bucket‑sort style structure).
These problems cover variations: distinctness, ordering, streaming, and two‑array interaction. Practising them will help you recognise when the top‑k pattern is the right tool.
How to Practice This
- Write the skeleton first – Draft the heap‑setup and the main loop before filling in edge cases.
- Run a dry‑run on paper – Simulate the algorithm with a small array to see how the heap evolves.
- Explain aloud – Use Call Assistant to rehearse your explanation; it will capture your wording and keep follow‑up questions on track, making the story feel natural.
FAQ
- When should I prefer quick‑select over a heap? Quick‑select gives average O(n) time and is ideal when you need the exact k th element and don’t need the whole sorted top‑k list. A heap is simpler to implement and works well when you also need to maintain the set dynamically.
- Is a heap always better than sorting? Not always. If k ≈ n or the input is already nearly sorted, the overhead of heap operations may outweigh the cost of a full sort. Check the ratio k/n first.
- How do I handle ties in top‑k frequency problems? Define a tie‑breaker (e.g., alphabetical order) and push a tuple (freq, word) into the heap so Python’s tuple comparison respects your rule.
- Can I use built‑in functions like
nlargest? Yes,heapq.nlargest(k, iterable, key=…)is a concise wrapper around the heap pattern and is acceptable in most interview settings, provided you can explain the underlying idea.
Frequently asked questions
When should I prefer quick‑select over a heap?
Quick‑select gives average O(n) time and is ideal when you need the exact k‑th element and don’t need the whole sorted top‑k list. A heap is simpler to implement and works well when you also need to maintain the set dynamically.
Is a heap always better than sorting?
Not always. If k is close to n or the input is already nearly sorted, the overhead of heap operations may outweigh the cost of a full sort. Look at the ratio k/n first.
How do I handle ties in top‑k frequency problems?
Define a tie‑breaker such as alphabetical order and push a tuple (frequency, word) into the heap so Python’s tuple comparison respects your rule.
Can I use built‑in functions like `heapq.nlargest`?
Yes, `heapq.nlargest(k, iterable, key=…)` is a concise wrapper around the heap pattern and is acceptable in most interview settings, as long as you can explain the underlying idea.
#coding pattern#top-k elements#interview prep#python#algorithm