Dynamic programming

O(n)·O(n) space
Whole table

Drag to pan; pinch or Ctrl+scroll to zoom, which stops at the whole table; arrow keys pan once the picture has focus. The headers stay put while you pan.

F(0), not yet filledF(1), not yet filledF(2), not yet filledF(3), not yet filledF(4), not yet filledF(5), not yet filledF(6), not yet filledF(7), not yet filledF(8), not yet filledF(9), not yet filledF(10), not yet filledF(0)0F(1)1F(2)2F(3)3F(4)4F(5)5F(6)6F(7)7F(8)8F(9)9F(10)10the tableFvalue→ i↓ F(i)

The table has 1 row and 11 columns, and nothing has been worked out yet. Nothing is filled until something asks for it, so the work starts at the right-hand end.

The table has 1 row and 11 columns, and nothing has been worked out yet. Nothing is filled until something asks for it, so the work starts at the right-hand end.
Answer so far—

F(i) = memo[i] ?? F(i−1) + F(i−2)

  1. 1ask for the cell you want
  2. 2the cell is already filled, so hand it back without recursing
  3. 3a base case: fill it and hand it back
  4. 4ask for the two cells behind it, which suspends this call until both answer
  5. 5add the two answers and write them into the cell
  6. 6stop: the cell that was asked for holds F(n)
Cells filled
0
Cells read
0
Values written
0
Answers already there
0

Complexity

BestO(n)
AverageO(n)
WorstO(n)
Extra spaceO(n)
2n at n=11 predicts 22; this run took 0.

Fibonacci, top-down memoised

This is the same recurrence and the same table as the bottom-up page, approached from the other end. Ask for F(n); it asks for F(n−1) and F(n−2); those ask for theirs, and so on down to the base cases. Each answer is written into the table on the way back up, and any call that finds its cell already filled returns immediately instead of recursing again. The table is not a plan here, it is a memory.

Its recurrence

F(i) = memo[i] ?? F(i−1) + F(i−2)

When it is the right choice

Top-down is the easier of the two to write, because it is the recursion you already had with three lines added, and it only ever computes the subproblems it actually needs — which matters when the table is large and sparse. Bottom-up avoids the call stack and is usually faster by a constant factor. On this table they do identical work, which is exactly why this pair is the place to compare them.

How it works

Worth noticing

Cost

Best
O(n)
Average
O(n)
Worst
O(n)
Extra space
O(n)
Table
one dimension
Accepts
n from 1 to 20

The limits are pedagogical rather than technical: this tool keeps the whole table in every recorded step, so the shape of the table sets the size of the trace directly, and a run has to stay short enough to sit and watch. An input that would take more than three thousand steps on this algorithm is refused before a single step is generated, from a formula in the input sizes rather than by running it and finding out.

An unfilled cell is drawn differently from a cell holding a zero — no fill, a dashed outline, and no number at all — because early in a run that difference is most of the picture.

Worth comparing

All dynamic programming algorithms