DEV Community

ScorbicLife
ScorbicLife

Posted on

Pitfalls while memoization

As practicing dynamic programming, I was implementing a function that returns the binomial coefficient nCr given n and r.

Naive formula:

function binomial_naive(n, r) { if (n < 0 || r < 0 || r > n) { return 0; } if (r === 0 || r === n) { return 1; } return binomial_naive(n-1, r-1) + binomial_naive(n-1, r); } 
Enter fullscreen mode Exit fullscreen mode

We can memoize this function to get O(r(n-r)) running time.

I was using Map<number, Map<number, number>>s but encountered a problem.

My initial memoization implementation had cache updating code and cache retrieval code interleaved, which made subtle bugs that only occurs only when some cache is computed.

I threw it away and coded a more straightforward implementation:

const cache = new Map(); function binomial(n, r) { if (!cache.has(n)) { cache.set(n, new Map()); } if (!cache.get(n).has(r)) { cache.get(n).set(r, binomial_naive(n, r)); } return cache.get(n).get(r); } function binomial_naive(n, r) { if (n < 0 || r < 0 || r > n) { return 0; } if (r === 0 || r === n) { return 1; } return binomial(n - 1, r) + binomial(n - 1, r - 1); } 
Enter fullscreen mode Exit fullscreen mode

Now I see that we could implement this using 2d arrays which makes it a little more straightforward.

Top comments (0)