Skip to content

state 8 of 32 · 6 min

Turning the recursion inside out

Memoisation starts at the top and recurses down. Tabulation starts at the bottom and fills upward, so nothing needs to recurse at all.

code
ways = array of size n + 1
ways[0] = 1
ways[1] = 1
for i from 2 to n:
    ways[i] = ways[i - 1] + ways[i - 2]
return ways[n]

Same answers, same complexity, no call stack.

What you gain and what you lose

Gain. No recursion depth limit, which matters: a memoised solution for n = 100000 overflows the stack in most languages while the loop is fine. Loops are also faster in practice, with no call overhead.

Lose. It computes every state, including ones the answer never needed. Memoisation computes only what is reachable, which for a sparse problem can be a large saving.

Fill order is the whole difficulty

A table only works if every value is already there when you need it. That is easy for stairs, where i depends on i - 1 and i - 2, so counting upwards is obviously right.

It is not always obvious. For a grid you fill row by row because each cell needs the one above and the one to the left. For intervals you fill by increasing length, not left to right, because a long interval is built from shorter ones inside it.

When a table gives a wrong answer, fill order is the first thing to check. The symptom is reading a cell that is still zero.

Which to use

Reach for memoisation first. Convert to a table when recursion depth is a risk, when the constant factor matters, or when you want to roll the table to save space, which is the next page.