Jaconir

Dynamic Programming

Unlock one of the most powerful algorithmic techniques by learning to break down complex problems into simpler, reusable pieces.

What Is Dynamic Programming?

Dynamic Programming (DP) is a method for solving complex problems by breaking them down into simpler, overlapping subproblems. The key idea is to solve each subproblem only once and store its result. When the same subproblem occurs again, you simply look up the stored result instead of re-calculating it. This technique is all about "remembering" the past to make the future easier.

A problem is a good candidate for DP if it has two properties:

  • Overlapping Subproblems: The problem can be broken down into smaller subproblems that are reused several times. (e.g., calculating `fib(5)` requires `fib(3)`, and so does calculating `fib(4)`).
  • Optimal Substructure: The optimal solution to the overall problem can be constructed from the optimal solutions of its subproblems.

There are two main approaches to DP:

  1. Memoization (Top-Down): You write a standard recursive function, but before any computation, you check if the result for the current state is already in your cache. If it is, you return it. If not, you compute it, store it, and then return it.
    Real-world Frontend Example: In React, `useMemo` is a direct application of memoization. You wrap an expensive calculation in `useMemo`, and it will only re-run if its dependencies change, preventing costly re-renders. Similarly, caching API responses to avoid re-fetching the same data is a form of memoization.
  2. Tabulation (Bottom-Up): You solve the problem iteratively, starting with the smallest possible subproblem and building up to the final solution. You typically use an array or matrix to store the results of subproblems in order.
Visualizing Overlapping Subproblems: Fibonacci
The Fibonacci sequence is the classic example for DP. To find `fib(4)`, a naive recursive approach calculates `fib(2)` twice. This is very inefficient. Dynamic Programming (specifically, **Memoization**) solves this by storing results so we only compute each value once.

Log

Click "Next Step" to begin.

1function fib(n) {
2 // Base case
3 if (n <= 1) {
4 return n;
5 }
6
7 // Recursive step
8 return fib(n - 1) + fib(n - 2);
9}
Interview Problem: Climbing Stairs
You are climbing a staircase. It takes `n` steps to reach the top. You can either climb 1 or 2 steps at a time. How many distinct ways can you climb to the top? This is a classic DP problem that uses the "tabulation" (bottom-up) approach.
?
?
?
?
?
?
Start. Create an array 'dp' to store solutions to subproblems.
1
2function climbStairs(n) {
3 if (n <= 1) return 1;
4
5 // dp[i] will store the number of ways to reach step i
6 let dp = new Array(n + 1);
7
8 // Base cases
9 dp[0] = 1;
10 dp[1] = 1;
11
12 for (let i = 2; i <= n; i++) {
13 // You can reach step i either from step i-1 or step i-2
14 dp[i] = dp[i - 1] + dp[i - 2];
15 }
16
17 return dp[n];
18}
Coding Challenge
You are climbing a staircase. It takes n steps to reach the top. Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?
Quick Quiz: Test Your Knowledge

What are the two main properties of a problem that suggests it can be solved with Dynamic Programming?

What is the term for the top-down DP approach where you store results of function calls?

What is the term for the bottom-up DP approach where you build a table of results iteratively?

In web development, using a cache to store the result of an expensive API call to avoid re-fetching is an example of what DP concept?

Go Deeper with "Grokking Algorithms"

For more beautifully illustrated explanations of Dynamic Programming, "Grokking Algorithms" is one of the best resources available for visual learners.

J
Dafin Edison J
Creator & Developer of Jaconir

I build things for the web. From immersive games to practical tools, my goal is to create products that people love to use and to share the knowledge I've gained along the way.