PROBLEM-SOLVING PATTERNS / ALGORITHM BRIEF

Top K elements

Top K problems ask for the k largest, smallest, most frequent, or closest items.

IntermediatePhase 03 / Topic 10 of 10Mental modelComplexityEdge cases
01

Overview

Top K problems ask for the k largest, smallest, most frequent, or closest items. The standard tool is a heap of size k: to keep the k largest, use a min-heap and evict the smallest whenever the heap grows past k. The heap's root is then the kth largest element.

This costs O(n log k) instead of O(n log n) for a full sort, and it works on streams where data never stops. Alternatives include quickselect (O(n) average) and bucket sort when values are bounded, such as frequencies.

A talent show with k finalist chairs

There are only k chairs on stage. Each new contestant is compared with the weakest finalist; if they are better, the weakest leaves and the newcomer sits. The weakest finalist is always easy to find because the min-heap keeps them on top.

02

When to use it

  • Phrases like k largest, k smallest, kth largest, top k frequent, k closest.
  • Data arrives as a stream and you must report the current top k.
  • n is large and k is small, so sorting everything is wasteful.
  • Merging k sorted lists (heap of k list heads).
03

Problem patterns it solves

Kth largest / smallest

Recognize it when: a single order statistic.

  • 215. Kth Largest Element in an Array
  • 703. Kth Largest Element in a Stream
  • 378. Kth Smallest Element in a Sorted Matrix
Top K by frequency

Recognize it when: most frequent elements or words.

  • 347. Top K Frequent Elements
  • 692. Top K Frequent Words
  • 451. Sort Characters By Frequency
K closest

Recognize it when: closest points to origin, closest values to x.

  • 973. K Closest Points to Origin
  • 658. Find K Closest Elements
K-way merge

Recognize it when: merge k sorted lists or find the smallest pairs across arrays.

  • 23. Merge k Sorted Lists
  • 373. Find K Pairs with Smallest Sums
  • 632. Smallest Range Covering Elements from K Lists
Greedy with a heap

Recognize it when: repeatedly take the largest or smallest: stones, tasks, sticks.

  • 1046. Last Stone Weight
  • 621. Task Scheduler
  • 1167. Minimum Cost to Connect Sticks
04

Where it is used in real software

Trending and leaderboards

Trending hashtags, top sellers, and game leaderboards keep the top K by score from streams of events.

Search ranking

Search engines score many candidate documents and keep only the top 10 to 100 with a bounded heap before final ranking.

Vector search

Nearest-neighbor search in embedding databases returns the top K most similar vectors, maintained with a heap.

Monitoring

Top K slowest endpoints or noisiest customers in observability tools, often approximated with Count-Min Sketch plus a heap.

05

Key terms

Min-heap of size k
Keeps the k largest; the root is the kth largest.
Max-heap of size k
Keeps the k smallest; the root is the kth smallest.
Quickselect
Partition-based selection in O(n) average time.
Bucket by frequency
Index an array by count to extract top frequencies in O(n).
06

Heap of size k

  1. 1
    Choose the opposite heap

    For the k largest, use a min-heap (so the weakest of the top k is on top to be evicted).

  2. 2
    Push each element

    heap.push(x).

  3. 3
    Evict when too big

    If heap.size > k, pop the root.

  4. 4
    Read the answer

    The heap holds the top k; the root is the kth largest.

07

Kth largest with k = 3

nums = [3, 2, 1, 5, 6, 4]

Step 1 / 6
xHeap after pushEvict?Heap (min-heap, size <= 3)
3[3]no[3]
2[2, 3]no[2, 3]
1[1, 2, 3]no[1, 2, 3]
5[1, 2, 3, 5]pop 1[2, 3, 5]
6[2, 3, 5, 6]pop 2[3, 5, 6]
4[3, 4, 5, 6]pop 3[4, 5, 6]

NOWx: 3 | Heap after push: [3] | Evict?: no | Heap (min-heap, size <= 3): [3]

The heap holds the 3 largest values {4, 5, 6}, and its root, 4, is the 3rd largest. Each step is O(log k).

08

Implementation

// JavaScript has no built-in heap; this minimal MinHeap is interview-readyclass MinHeap {  constructor(compare = (a, b) => a - b) { this.data = []; this.compare = compare; }  get size() { return this.data.length; }  peek() { return this.data[0]; }  push(x) {    const d = this.data;    d.push(x);    let i = d.length - 1;    while (i > 0) {      const p = (i - 1) >> 1;      if (this.compare(d[i], d[p]) >= 0) break;      [d[i], d[p]] = [d[p], d[i]];      i = p;    }  }  pop() {    const d = this.data;    const top = d[0];    const last = d.pop();    if (d.length) {      d[0] = last;      let i = 0;      while (true) {        const l = 2 * i + 1, r = l + 1;        let m = i;        if (l < d.length && this.compare(d[l], d[m]) < 0) m = l;        if (r < d.length && this.compare(d[r], d[m]) < 0) m = r;        if (m === i) break;        [d[i], d[m]] = [d[m], d[i]];        i = m;      }    }    return top;  }} function findKthLargest(nums, k) {  const heap = new MinHeap();  for (const x of nums) {    heap.push(x);    if (heap.size > k) heap.pop();  }  return heap.peek();} // 347: bucket sort by frequency, O(n)function topKFrequent(nums, k) {  const freq = new Map();  for (const x of nums) freq.set(x, (freq.get(x) ?? 0) + 1);  const buckets = Array.from({ length: nums.length + 1 }, () => []);  for (const [value, count] of freq) buckets[count].push(value);  const result = [];  for (let f = buckets.length - 1; f > 0 && result.length < k; f--) {    result.push(...buckets[f]);  }  return result.slice(0, k);}
09

Complexity and performance

Heap of size kO(n log k)

O(k) space.

Full sortO(n log n)

Simple but wasteful for small k.

QuickselectO(n) average

O(n^2) worst case; random pivot.

Bucket by frequencyO(n)

Frequencies are bounded by n.

Merge k listsO(N log k)

N total nodes.

10

Trade-offs

Heap vs quickselect

Quickselect is faster on average for a one-off array but modifies it and does not work on streams. The heap handles streams and guarantees O(n log k).

Returning sorted output

A heap returns the top k unsorted; sort them at the end (O(k log k)) if order is required.

11

Variants and related techniques

Two heaps for medians

A max-heap for the lower half and a min-heap for the upper half give the running median.

Tie-breaking

Top K Frequent Words breaks ties alphabetically; the comparator must reflect that in reverse for a min-heap.

Binary search on value

In sorted matrices, binary search the answer value and count elements <= mid.

12

Common mistakes

  • Using a max-heap to find the k largest.

    Fix: That needs all n elements in the heap. A min-heap of size k is the efficient choice.

  • Java PriorityQueue is a min-heap by default.

    Fix: Use Collections.reverseOrder() or a comparator for a max-heap.

  • Comparator subtraction overflow.

    Fix: Use Integer.compare or Long for distances.

13

Interview questions

Why a min-heap for the k largest?

The root of a min-heap is the smallest of the k kept values, which is exactly the one to evict when a larger value arrives. This keeps the heap at size k.

Can you do better than O(n log k)?

Quickselect is O(n) on average. For frequencies, bucket sort is O(n) because counts range from 1 to n.

14

Practice problems

ProblemDifficultyWhat it trains
703. Kth Largest Element in a StreamEasyStreaming heap.
1046. Last Stone WeightEasyMax-heap simulation.
215. Kth Largest Element in an ArrayMediumHeap vs quickselect.
347. Top K Frequent ElementsMediumBucket sort.
973. K Closest Points to OriginMediumMax-heap by distance.
23. Merge k Sorted ListsHardK-way merge.