Debugging challengeIntermediate
Top-K with the heap pointing the wrong way
Scenario
A dashboard shows the k highest scores out of n (n up to 10⁸ streamed from disk, k = 100). The current implementation is correct but runs out of memory and is slow. A junior engineer "fixed" the memory issue in top_k_v2, which is now wrong. Diagnose both versions.
Broken
1import heapq2 3def top_k_v1(scores, k):4 # correct but heavy5 heap = []6 for s in scores:7 heapq.heappush(heap, -s)8 return [-heapq.heappop(heap) for _ in range(k)]9 10 11def top_k_v2(scores, k):12 # "memory fix" — keeps only k elements13 heap = []14 for s in scores:15 heapq.heappush(heap, -s)16 if len(heap) > k:17 heapq.heappop(heap)18 return sorted((-x for x in heap), reverse=True)19 20print(top_k_v2([5, 1, 9, 3, 7], 2)) # prints [3, 1], expected [9, 7]The corrected version appears here once you have revealed everything below.
Your task
- Explain why
top_k_v1is correct and what its time and space costs are forn = 10⁸,k = 100. - Explain exactly why
top_k_v2returns the two *smallest* values. - Write the correct bounded-size version and state the invariant the heap maintains.
- Compare with
heapq.nlargest, sorting, and quickselect. When would you choose each?
DebuggingOptimizationComplexity Analysis
Work it out
Write your analysis before revealing anything. The self-check below compares it against what a strong answer contains.
Reveal
Progressive — each section builds on the previous one.
The bug
Why it happens
The fix
Edge cases
Complexity
What this tests
Self-check
Tick what your analysis covered. Be honest — this feeds your readiness profile.