Basis Lab

The Patterns Behind Most Coding Problems

Keeping Only the Best Few Without Sorting the Rest

Last timeTotals You Compute Once

Holding the best k of a stream needs one comparison per arrival against the weakest you have kept, which costs n log k instead of n log n and k memory instead of n.

The question is the three largest values of A=[2,7,11,15,1,8,4,4,9,3]A = [2, 7, 11, 15, 1, 8, 4, 4, 9, 3],

ten values totalling 64. The obvious answer is to sort the list and read the

last three off the end, and the obvious answer is correct, which is what makes

this pattern worth deriving rather than asserting. Sorting arranges all ten

values with respect to one another. The question asked for three of them and

did not ask for them in order, so nearly all of that arrangement is bought and

then thrown away.

The structure being exploited is that the answer set is small. If only three

values can ever be in the answer, then every arrival has exactly one question

to answer, which is whether it is better than the worst of the three being

held.

The weakest of the few you have kept

Hold the best three seen so far. The value that has to be available instantly

is not the best of them but the worst, because that is the one an arrival has to

beat and the one that leaves when it does. So the container is a heap whose root

is its smallest element, which reads backwards the first time and is the whole

idea. Write kk for how many are kept, here 3, and nn for how many arrive,

here 10.

FIG 1One pass over A, keeping the best three
stepthe arrivalthe three keptthe threshold, smallest of the keptwhat the arrival cost
122none yetan insertion, the container is not full
272, 7none yetan insertion
3112, 7, 112an insertion, and from here a threshold exists
4157, 11, 157beats 2, so 2 leaves and the threshold rises to 7
517, 11, 157one comparison and it is gone
688, 11, 158beats 7, so 7 leaves and the threshold rises to 8
748, 11, 158one comparison and it is gone
848, 11, 158the duplicate is dismissed the same way
999, 11, 159beats 8, so 8 leaves and the threshold rises to 9
1039, 11, 159one comparison and it is gone
10 steps
The answer is 15, 11 and 9, which are indeed the three largest values of A. Four of the ten arrivals were dismissed on a single comparison and never entered the container at all, and the threshold only ever rises, from 2 to 7 to 8 to 9. That monotone threshold is the reason later arrivals are cheaper than earlier ones, and it is the thing to watch when a run of this looks slow.

Three arrivals filled the container, three replaced the root, and four were

dismissed for one comparison each. Nothing was ever sorted.

The lesson stops here

6 more paragraphs to go

You have read the opening. The rest of the argument, the problems that check whether it landed, and the lines worth keeping at the end all come with a plan.

The first lesson of every course in the library reads the whole way through, free, so you can see exactly what the rest of them are.

See the planThe contents

This is the reading half

Starting the course gives you your own copy of it. Every idea on every page has problems standing under it, marked with a reason rather than a tick, and any sentence you do not believe can be opened and argued with. None of that can happen on a page nobody owns.

The contents

The rest of this course

  1. 01What a Pattern Is Actually Exploiting, and Why It Is Never Cleverness
  2. 02Two Ends Moving Inward, and the Proof That Nothing Is Lostopening only
  3. 03A Window That Slides, and Why Its Work Stays Linearopening only
  4. 04Remembering What You Have Seen, and What the Memory Costsopening only
  5. 05Totals You Compute Once, Then Read by Subtractionopening only
  6. 06Keeping Only the Best Few Without Sorting the Restyou are here
  7. 07Searching the Answer Instead of the Inputopening only
  8. 08Choosing the Pattern From the Words of the Problemopening only

Read alongside