Skip to main content
LeetCode Prep
CHAPTER 13 Beginner

Dynamic Programming Basics

Updated: May 18, 2026
5 min read

# CHAPTER 13

Dynamic Programming Basics

1. Chapter Introduction

Dynamic Programming (DP) is the most feared topic in coding interviews. It feels like magic when you watch someone solve a DP problem, but it is actually a highly structured, repeatable process. Dynamic Programming is simply an optimization over plain Recursion. Whenever a recursive algorithm solves the *exact same sub-problem* multiple times, we can cache the result to save time. This chapter breaks down DP into two methods: Top-Down (Memoization) and Bottom-Up (Tabulation).

2. The Core Concept (Why DP exists)

Consider calculating the 5th Fibonacci number: F(5) = F(4) + F(3). To calculate F(4), we need F(3) + F(2). Notice that F(3) is being calculated twice! In a pure recursive tree for F(50), the function F(3) might be recalculated millions of times. This makes the time complexity a catastrophic O(2^N).

Dynamic Programming says: "Those who cannot remember the past are condemned to repeat it." If we calculate F(3) once, and save the answer in a Hash Map or Array, the next time the recursion asks for F(3), we instantly return the saved answer. The Time Complexity drops instantly from O(2^N) to O(N).

3. Method 1: Top-Down with Memoization

"Memoization" comes from "memo" (writing down a note to remember). You write the standard Recursive Backtracking function, but you add a Cache (a Hash Map or Array) to store the results of function calls.

*Example: Climbing Stairs (LeetCode 70)* *Prompt:* You are climbing a staircase. It takes n steps. You can climb 1 or 2 steps at a time. How many distinct ways can you climb to the top?

python
123456789101112131415161718
def climbStairs_Memo(n):
    cache = {} # The Memoization dictionary
    
    def dfs(step):
        # Base Cases
        if step == n: return 1
        if step > n: return 0
        
        # Check Cache BEFORE calculating
        if step in cache:
            return cache[step]
            
        # Recursive Relation: Ways to top = (Take 1 step) + (Take 2 steps)
        cache[step] = dfs(step + 1) + dfs(step + 2)
        return cache[step]
        
    return dfs(0)
# Time: O(N), Space: O(N)

4. Method 2: Bottom-Up Tabulation

Tabulation means building a table (an Array). Instead of starting at the top n and recursively breaking it down, we start at 0 and use a for loop to build up to n. *Pros:* No recursion means no risk of StackOverflowError and less overhead memory.
python
12345678910111213
def climbStairs_Tabulation(n):
    if n <= 2: return n
    
    dp = [0] * (n + 1) # Create the DP Table
    dp[1] = 1 # Base cases
    dp[2] = 2
    
    for i in range(3, n + 1):
        # State Transition Equation
        dp[i] = dp[i - 1] + dp[i - 2]
        
    return dp[n]
# Time: O(N), Space: O(N)

5. The Ultimate Optimization: Space Reduction

Look at the for loop in the Tabulation method. dp[i] = dp[i - 1] + dp[i - 2]. To calculate step 5, we only need to know step 4 and step 3. We absolutely do not care about step 1 or step 2 anymore. Therefore, we do not need an entire array of size N. We only need two integer variables!
python
123456789101112
def climbStairs_Optimized(n):
    if n <= 2: return n
    prev1 = 1
    prev2 = 2
    
    for _ in range(3, n + 1):
        current = prev1 + prev2
        prev1 = prev2
        prev2 = current
        
    return prev2
# Time: O(N), Space: O(1) Constant Space!

6. The 4-Step Framework for Solving DP

Do not try to jump straight to the O(1) optimized solution. You will fail. Use this framework in an interview:
  1. 1. Define the State: What parameters define your current situation? (e.g., step_number).
  1. 2. Determine the Base Cases: What is the simplest possible input? (e.g., if step == n: return 1).
  1. 3. Find the State Transition Equation: How does a state relate to its previous states? (e.g., dp[i] = dp[i-1] + dp[i-2]).
  1. 4. Add Memoization/Tabulation: Cache the results.

7. Pattern: 1D Dynamic Programming (House Robber)

*Prompt:* You are a robber. You cannot rob adjacent houses. Maximize your loot. houses = [1, 2, 3, 1]. *State Transition:* At any house i, you have two choices:
  • Option A: Rob this house i + the loot from house i - 2.
  • Option B: Do NOT rob this house. Keep the loot from house i - 1.
*Equation:* dp[i] = max(houses[i] + dp[i - 2], dp[i - 1])

8. Mini Project: Coin Change

*Prompt:* Given coin denominations [1, 2, 5] and an amount = 11, find the minimum number of coins to make the amount. *DP Table:* Array of size 12 (amount + 1), initialized to infinity. dp[0] = 0. *Equation:* dp[amt] = 1 + min(dp[amt - 1], dp[amt - 2], dp[amt - 5])

9. Common Mistakes

  • Off-by-One Array Sizes: When creating a DP table for an integer N, you usually need an array of size N + 1 so that dp[N] is a valid index.
  • Skipping the Brute Force: In an interview, explicitly write out the slow recursive tree first. Show the interviewer the repeated work. *Then* add the Memoization dictionary. It proves you understand *why* DP is needed.

10. Best Practices

  • Top-Down First: Top-Down Memoization is usually much more intuitive to write because it follows natural human logic (Recursion). Bottom-up Tabulation requires figuring out the exact loop indices, which can be tricky under pressure. Stick to Memoization unless asked to optimize.

11. Exercises

  1. 1. What is the Space Complexity of the Top-Down Memoized Climbing Stairs algorithm?
  1. 2. Write the State Transition equation for the House Robber problem.

12. MCQs

Question 1

What specific algorithmic flaw does Dynamic Programming (DP) attempt to solve?

Question 2

What is "Top-Down" Dynamic Programming?

Question 3

What is "Bottom-Up" Dynamic Programming?

Question 4

In the Climbing Stairs problem, the recursive relation is f(n) = f(n-1) + f(n-2). What famous mathematical sequence does this model?

Question 5

When transforming the Climbing Stairs Tabulation array into O(1) Space, why are we able to discard the array?

Question 6

What is a "State Transition Equation" in Dynamic Programming?

Question 7

In the House Robber problem (cannot rob adjacent houses), what two options must be evaluated at every single house i to find the maximum loot?

Question 8

When initializing a Bottom-Up DP Array (Tabulation) to solve for target N, what is the most common size the array needs to be?

Question 9

Which DP approach is generally less risky during an interview if you are afraid of StackOverflowErrors caused by massive inputs?

Question 10

How should a candidate approach a DP problem on the whiteboard?

14. Interview Questions

  • Q: "You are given an integer array cost where cost[i] is the cost of ith step on a staircase. Once you pay the cost, you can either climb one or two steps. Find the minimum cost to reach the top of the floor." (LeetCode 746).

15. FAQs

  • Q: Does every recursive function need Dynamic Programming?
A: No. DP is ONLY applicable if there are "Overlapping Sub-problems." Standard Tree DFS Traversals don't calculate the same node twice, so DP is useless there.

16. Summary

Dynamic Programming trades Space for Time by caching the results of overlapping recursive sub-problems. "Top-Down" Memoization is highly intuitive: just add a Hash Map to your Backtracking function. "Bottom-Up" Tabulation builds an array iteratively, saving Call Stack memory. Master the 4-step framework: define the State, the Base Cases, the State Transition Equation, and Cache it.

17. Next Chapter Recommendation

1D DP is manageable. But what if we are comparing two entire strings against each other, or navigating a 2D grid? In Chapter 14: Advanced Dynamic Programming, we introduce 2D Matrices, solving the infamous Knapsack problem and Longest Common Subsequence.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·