Senior · Algorithms

Top-K with a bounded min-heap

How can a stream keep its largest k values without sorting everything?

Try explaining this aloud before opening the answer. State your assumptions and trace a boundary case.

ALGORITHM LAB · STEP THROUGH THE INVARIANT

[5, 1, 9, 3, 8], k=3

STEP 1 / 6

Keep at most k winners

Input
50
11
92
33
84
Min-heap
∅ Empty

The root is the smallest retained winner.

Computed traces for these inputs. Indexes identify cell positions; active cells are labeled as well as highlighted. Compare a boundary case using the scenario selector. No code is sent to a server.

EXAMPLE · FRAGMENT UNLESS A COMPLETE PROGRAM IS SHOWN

go
type minInts []int

func (h minInts) Len() int           { return len(h) }
func (h minInts) Less(i, j int) bool { return h[i] < h[j] }
func (h minInts) Swap(i, j int)      { h[i], h[j] = h[j], h[i] }
func (h *minInts) Push(x any)        { *h = append(*h, x.(int)) }
func (h *minInts) Pop() any {
	old := *h
	x := old[len(old)-1]
	*h = old[:len(old)-1]
	return x
}

// Requires imports container/heap and sort.
func TopK(xs []int, k int) []int {
	if k <= 0 {
		return nil
	}
	h := &minInts{}
	for _, x := range xs {
		if h.Len() < k {
			heap.Push(h, x)
		} else if x > (*h)[0] {
			(*h)[0] = x
			heap.Fix(h, 0)
		}
	}
	out := append([]int(nil), (*h)...)
	sort.Ints(out)
	return out
}
Reveal a strong answer
  1. Keep a min-heap of at most k values. Its root is the smallest retained winner; once full, discard an incoming value no larger than the root, otherwise replace the root and restore the heap.

  2. The invariant is that after each prefix the heap contains its k largest values, or every value if fewer than k arrived. Duplicates count separately unless the problem explicitly asks for distinct values.

  3. Validate k, avoid retaining the full stream and sort only the final winners if ordered output is needed. container/heap expects you to implement its interface; its Push/Pop methods have different roles from calling heap.Push/heap.Pop.

Common trap

A max-heap of k values exposes the largest winner, which is the wrong item to evict.

Complexity & use

O(n log k) time and O(k) storage, plus O(k log k) if final sorted output is requested.

Try it

Trace [5,1,9,3,8] with k3. Which items survive?

Worked solution

Fill with5,1,9. Replace root1 with3, then root3 with8. Winners are5,8,9; heap internal order is not sorted order. Test k0, k>n and duplicate cutoffs.

Change the constraint

How would you merge top-K results from several partitions without collecting every original value?

How did you do?

Self-assessment, not a compiler pass or interview score. Explain the reasoning unaided before marking understood.

Not marked. Progress stays on this browser, separate from course completion.

Primary references

Checked 2026-10-20. Use documentation for your pinned runtime, driver and tool version.