Java Notes
Complete guide to Dynamic Programming in Java covering memoization, tabulation, classical DP problems (Fibonacci, Knapsack, LCS, LIS, Coin Change), time/space optimization, and interview patterns.
What is Dynamic Programming?
Dynamic Programming (DP) is an algorithmic technique that solves complex problems by breaking them down into simpler overlapping subproblems, solving each subproblem only once, and storing the results for future use. It transforms exponential-time recursive solutions into polynomial-time iterative (or memoized) solutions.
The Two Key Properties
For a problem to be solvable with DP, it must have:
1. Overlapping Subproblems: The same subproblems are solved multiple times during recursion. DP stores (caches) these results to avoid redundant computation.
2. Optimal Substructure: The optimal solution to the problem can be constructed from optimal solutions of its subproblems.
Analogy
Imagine you're asked: "What's 1+1+1+1+1+1+1+1+1+1?"
You count: "10." Now someone adds "+1" to the end. You don't recount from scratch — you remember the previous answer (10) and add 1 → 11.
That's Dynamic Programming: remembering past results to avoid recomputation.
Two Approaches to DP
1. Top-Down (Memoization)
- Start with the original problem and recursively break it down
- Use a cache (array or HashMap) to store results of subproblems
- When a subproblem is encountered again, return the cached result
- Natural extension of recursive thinking
2. Bottom-Up (Tabulation)
- Start with the smallest subproblems and build up to the solution
- Use a table (array) to store results iteratively
- No recursion — avoids stack overflow
- Usually more space-efficient (can sometimes reduce dimensions)
Fibonacci — The Classic DP Example
Pure Recursion (Exponential — BAD)
public class FibonacciRecursive {
static int fib(int n) {
if (n <= 1) return n;
return fib(n - 1) + fib(n - 2); // Recomputes same values!
}
public static void main(String[] args) {
System.out.println("fib(10) = " + fib(10));
System.out.println("fib(20) = " + fib(20));
// fib(50) would take MINUTES — exponential time!
}
}fib(10) = 55 fib(20) = 6765
Problem: fib(5) computes fib(3) twice, fib(2) three times, etc. Time: O(2^n).
Recursion Tree for fib(5):
Top-Down with Memoization (O(n))
fib(40) = 102334155 First 15: 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
Time: O(n) — each subproblem computed once. Space: O(n) — memo array + recursion stack.
Bottom-Up Tabulation (O(n) time, O(n) space)
fib(10) = 55 fib(40) = 102334155 fib(50) = 1264937032
Space-Optimized (O(1) space)
Since each Fibonacci value only depends on the previous two, we don't need the entire array:
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610
Time: O(n), Space: O(1) — optimal!
Climbing Stairs Problem
Problem: You can climb 1 or 2 stairs at a time. How many distinct ways to reach step n?
Steps 1: 1 ways Steps 2: 2 ways Steps 3: 3 ways Steps 4: 5 ways Steps 5: 8 ways Steps 6: 13 ways Steps 7: 21 ways Steps 8: 34 ways Steps 9: 55 ways Steps 10: 89 ways
Dry Run for n=4:
0/1 Knapsack Problem
Problem: Given n items with weights and values, and a knapsack capacity W, find the maximum value you can carry without exceeding the weight limit. Each item can be included at most once.
Items: Item 1: weight=2, value=3 Item 2: weight=3, value=4 Item 3: weight=4, value=5 Item 4: weight=5, value=6 Maximum value: 10
Time: O(n × W), Space: O(n × W)
Dry Run (partial DP table):
| i=0 | 0 0 0 0 0 0 0 0 0 |
| i=1 | 0 0 3 3 3 3 3 3 3 |
| i=2 | 0 0 3 4 4 7 7 7 7 |
| i=3 | 0 0 3 4 5 7 8 9 9 |
| i=4 | 0 0 3 4 5 7 8 9 10 |
Longest Common Subsequence (LCS)
Problem: Find the length of the longest subsequence common to two strings.
String 1: ABCBDAB String 2: BDCAB LCS length: 4
Time: O(m × n), Space: O(m × n)
Coin Change Problem
Problem: Given coins of different denominations and a total amount, find the minimum number of coins needed.
Coins: [1, 5, 10, 25] Amount 11 → Min coins: 2 Amount 30 → Min coins: 2 Amount 7 → Min coins: 3 Amount 0 → Min coins: 0
Dry Run for amount=11, coins=[1,5,10,25]:
Longest Increasing Subsequence (LIS)
Array: [10, 22, 9, 33, 21, 50, 41, 60] LIS length: 5
Time: O(n²), Space: O(n) (Can be optimized to O(n log n) with binary search)
Edit Distance (Levenshtein Distance)
Problem: Find minimum operations (insert, delete, replace) to convert one string to another.
kitten → sitting : 3 operations sunday → saturday : 3 operations abc → abc : 0 operations
Subset Sum Problem
Problem: Given a set of positive integers, determine if there is a subset that sums to a target.
Set: [3, 34, 4, 12, 5, 2] Target 9: true Target 30: false Target 11: true Target 7: true
DP Problem-Solving Framework
Step-by-Step Approach
- Identify if it's a DP problem:
- Can you solve it recursively?
- Are there overlapping subproblems?
- Does optimal substructure exist?
- Define the state:
- What parameters uniquely identify a subproblem?
- Example:
dp[i]= answer for first i elements
- Write the recurrence relation:
- How does
dp[i]depend on smaller subproblems? - Example:
dp[i] = dp[i-1] + dp[i-2]
- Identify base cases:
- What are the trivial subproblems you can solve directly?
- Choose approach:
- Top-down (memoization) or Bottom-up (tabulation)
- Optimize space if possible (use only previous row/values)
Common Mistakes
- Incorrect base cases — forgetting to handle edge cases (n=0, empty arrays)
- Wrong recurrence relation — not considering all possible transitions
- Off-by-one indexing — confusion between 0-indexed and 1-indexed
- Not recognizing DP — solving with brute force when DP applies
- Integer overflow — large DP values exceeding int range
- Insufficient memo/table size — allocating array too small
- Not optimizing space — using 2D table when 1D suffices
Best Practices
- Start with recursion — understand the problem recursively first
- Draw the recursion tree — identify overlapping subproblems visually
- Use meaningful state names —
dp[i][j]with clear comments - Test with small inputs — verify by hand for n=3,4,5
- Print the DP table for debugging
- Optimize space after correctness is verified
- Consider constraints — if n ≤ 10^3, O(n²) is fine; if n ≤ 10^5, need O(n log n)
- Learn common patterns — knapsack, LCS, LIS, grid paths, intervals
Interview Questions
Q1: What is Dynamic Programming? An algorithmic technique that solves problems by breaking them into overlapping subproblems, solving each once, and storing results to avoid recomputation.
Q2: What are the two approaches to DP? Top-down (memoization with recursion) and Bottom-up (tabulation with iteration).
Q3: When should you use DP? When a problem has overlapping subproblems AND optimal substructure — usually optimization or counting problems.
Q4: What is memoization? Storing results of expensive function calls and returning the cached result when the same inputs occur again.
Q5: Memoization vs Tabulation? Memoization: recursive, top-down, solves only needed subproblems. Tabulation: iterative, bottom-up, solves all subproblems, no recursion stack.
Q6: Time complexity of 0/1 Knapsack? O(n × W) where n is number of items and W is knapsack capacity. This is pseudo-polynomial.
Q7: How to identify if a problem is DP? Look for: "find minimum/maximum", "count number of ways", "is it possible", overlapping recursive calls, and optimal substructure.
Q8: What is the difference between DP and Greedy? DP explores all possibilities and guarantees optimal. Greedy makes locally optimal choices and doesn't always give global optimal.
Q9: How to reconstruct the solution (not just the value)? Backtrack through the DP table: at each cell, determine which choice was made (include/exclude) and trace the path.
Q10: Can DP solve problems with exponential state space? Only if the number of unique states is polynomial. If states are truly exponential, DP doesn't help.
Exam Focus
Revise definitions, diagrams, examples, and short-answer points for Dynamic Programming in Java.
Interview Use
Prepare one clear explanation, one practical example, and one common mistake for this Java Master Course topic.
Search Terms
java-master-course, java master course, java, master, course, dsa, dynamic, programming
Related Java Master Course Topics