The pattern: the k-th smallest by counting
When the values cannot all be listed, search over the value itself: the k-th smallest is the first v with at least k values at or below it.
Search the value, count the rest
Some k-th smallest questions come with far too many values to sort: a multiplication table with 9 × 10⁸ cells, every pairwise distance in an array of 10⁴ numbers. But counting how many values are at most v is often cheap, and that count only grows as v grows. So the k-th smallest is a first-true search:
k-th smallest by counting
kth(k)
- count(v) = how many values are ≤ v. It never decreases as v increases.
- lo = the smallest value, hi = the largest.
- First-true search for the first v with count(v) ≥ k.
- Return lo.
Why the answer is a real value
The search runs over every integer in the range, most of which may not appear among the values at all. The answer still does. At the returned v, count(v) ≥ k but count(v − 1) < k, so some value equals v exactly: the count went up between v − 1 and v. No separate check is needed.
Worked example: a multiplication table
In the m × n table the row i holds i, 2i, …, n × i. The values at most v in row i number min(⌊v / i⌋, n), so count(v) is a sum over the m rows: O(m) per test, and no table is built.
The 7th smallest value of the 3 × 4 multiplication table.
-
Step 1 / 6k7
The 3 × 4 table, drawn only to show the counts. Values run from 1 to 12.
-
Step 2 / 6lo1mid6hi12count9
count(6) = min(6/1, 4) + min(6/2, 4) + min(6/3, 4) = 4 + 3 + 2 = 9. At least 7: hi = 6.
-
Step 3 / 6lo1mid3hi6count5
count(3) = min(3/1, 4) + min(3/2, 4) + min(3/3, 4) = 3 + 1 + 1 = 5. Fewer than 7: lo = 4.
-
Step 4 / 6lo4mid5hi6count7
count(5) = min(5/1, 4) + min(5/2, 4) + min(5/3, 4) = 4 + 2 + 1 = 7. At least 7: hi = 5.
-
Step 5 / 6lo4mid4hi5count7
count(4) = min(4/1, 4) + min(4/2, 4) + min(4/3, 4) = 4 + 2 + 1 = 7. At least 7: hi = 4.
-
Step 6 / 6answer4
lo = hi = 4: count(4) = 7 ≥ 7 and count(3) = 5 < 7. The answer is 4.
Against O(m × n log(m × n)) to build and sort the table.
Three counting functions
The search is identical in every problem of this module. The work is in counting fast.
| Problem | count(v): values ≤ v | Cost per count |
|---|---|---|
| k-th smallest in a multiplication table | Σ over rows i of min(⌊v / i⌋, n) | O(m) |
| k-th smallest in a row-and-column-sorted matrix | staircase walk from the bottom-left corner, adding the cells above each step | O(n) |
| k-th smallest pair distance | sort once; for each right end, two pointers find how many earlier values are within v | O(n) |
A heap also finds the k-th smallest by popping k times, at O(k log n). It wins when k is small; counting wins when k can be as large as the number of values, which is how these problems are usually set.