Card 08/ 08

RecapDifficulty: Advanced1 min

Recap: Optimising a Solution

Cost each step, compare the largest with the best conceivable runtime, remove its waste with a standard move, and say what the move costs.

Optimising a correct solution follows six steps:

  1. Cost each step and find the one that dominates.
  2. State the best conceivable runtime: the cost of reading the input and writing the output.
  3. If the dominant step already matches it, stop.
  4. Name the waste in that step: a bottleneck, unnecessary work or duplicated work.
  5. Apply the standard move that removes it.
  6. State the memory the move costs, then cost the solution again from step 1.

Each kind of waste has a sign in the code and a move that removes it.

Kinds of waste and the moves that remove them
Kind of wasteHow it showsStandard moveMemory it costs
BottleneckA search of a list inside a loopA hash set or mapO(n)
BottleneckA check of every pair in a sorted arrayTwo pointersO(1)
Duplicated workRange totals added up again and againPrefix sumsO(n), or O(1) in a single pass
Duplicated workThe same recursive call made many timesMemoisationOne entry per distinct call
Unnecessary workEvery value sorted when only the smallest few are neededA heapO(k) for k values kept
BottleneckComparing every item with every otherSorting, then a scan or a search by halvingThe sort's

Speed up only the step that dominates, since a faster line elsewhere leaves the total almost unchanged, and stop at the best conceivable runtime, where only memory can still improve.