🧱 Linear DP: Building Answers One Step at a Time
Imagine you’re climbing a staircase, but each step you take depends on where you’ve been. That’s Dynamic Programming — remembering the past to make the future easier.
🎯 What is Linear DP?
Think of Linear DP like a chain of dominoes. You set up each domino based on the ones before it. When you push the first one, the rest fall in order.
In simple words:
- You have a row of problems (like boxes numbered 1, 2, 3…)
- Each box’s answer depends on boxes before it
- You solve them one by one, left to right
- You remember each answer so you don’t repeat work
graph TD A["Box 1"] --> B["Box 2"] B --> C["Box 3"] C --> D["Box 4"] D --> E["... Box N"]
🐰 The Fibonacci Pattern: The Mother of All DP
The Story of Two Bunnies
Once upon a time, a farmer had 1 pair of baby bunnies. Every month:
- Baby bunnies grow up (take 1 month)
- Grown-up bunnies make 1 new baby pair
How many bunny pairs after 6 months?
| Month | Baby Pairs | Adult Pairs | Total |
|---|---|---|---|
| 1 | 1 | 0 | 1 |
| 2 | 0 | 1 | 1 |
| 3 | 1 | 1 | 2 |
| 4 | 1 | 2 | 3 |
| 5 | 2 | 3 | 5 |
| 6 | 3 | 5 | 8 |
See the pattern? Each total = previous two totals added together!
1, 1, 2, 3, 5, 8, 13, 21, 34...
This is the Fibonacci sequence — and it’s EVERYWHERE in DP!
The Magic Formula
fib(n) = fib(n-1) + fib(n-2)
Translation: To know today’s answer, just add yesterday’s and the day before’s!
Why This Matters
The Fibonacci pattern appears whenever:
- Current state = combining 1 or 2 previous states
- You’re counting ways to reach something
- You’re building something step by step
graph TD F5["fib 5 = 5"] --> F4["fib 4 = 3"] F5 --> F3a["fib 3 = 2"] F4 --> F3b["fib 3 = 2"] F4 --> F2a["fib 2 = 1"]
🪜 Climbing Stairs: Your First DP Adventure!
The Problem
You’re at the bottom of a staircase with n steps. You can climb either 1 step or 2 steps at a time. How many different ways can you reach the top?
The “Aha!” Moment
Where can you be right before the top step?
Only two places:
- One step below (then take 1 step)
- Two steps below (then take 2 steps)
So the total ways = ways to step (n-1) + ways to step (n-2)
Wait… that’s Fibonacci! 🎉
Visual Example: 4 Steps
Ways to reach Step 4:
Step 4: ⭐ (Goal!)
↗️ (take 1) ↗️ (take 2)
Step 3 Step 2
(3 ways) (2 ways)
Total: 3 + 2 = 5 ways!
All 5 ways to climb 4 steps:
- 1→1→1→1
- 1→1→2
- 1→2→1
- 2→1→1
- 2→2
The Code
public int climbStairs(int n) {
if (n <= 2) return n;
int prev2 = 1; // ways for step 1
int prev1 = 2; // ways for step 2
for (int i = 3; i <= n; i++) {
int current = prev1 + prev2;
prev2 = prev1;
prev1 = current;
}
return prev1;
}
Why only 2 variables? We only need the last two answers. Old answers can be forgotten — just like a caterpillar that only remembers its last 2 moves!
🏠 House Robber: The Greedy Thief’s Dilemma
The Story
You’re a very careful thief 🥷 (don’t worry, it’s just pretend!). Houses line up on a street, each with money inside.
The catch: If you rob two houses next to each other, alarms go off! 🚨
Goal: Steal the MOST money without triggering alarms.
The Thinking Process
At each house, you ask yourself:
- Rob this house → Add its money, but SKIP the previous house
- Skip this house → Keep whatever you had from before
House: [💰2] [💰7] [💰9] [💰3] [💰1]
Index: 0 1 2 3 4
Building the Solution
| At House | Rob It? | Best if Rob | Best if Skip | Max So Far |
|---|---|---|---|---|
| 0 ($2) | ✅ | 2 | 0 | 2 |
| 1 ($7) | ✅ | 7 | 2 | 7 |
| 2 ($9) | ✅ | 2+9=11 | 7 | 11 |
| 3 ($3) | ❌ | 7+3=10 | 11 | 11 |
| 4 ($1) | ✅ | 11+1=12 | 11 | 12 |
Answer: $12 (Rob houses 0, 2, and 4)
The Magic Formula
dp[i] = max(dp[i-1], dp[i-2] + money[i])
└─skip it─┘ └──rob it + skip neighbor──┘
The Code
public int rob(int[] nums) {
if (nums.length == 1) return nums[0];
int prev2 = 0;
int prev1 = nums[0];
for (int i = 1; i < nums.length; i++) {
int current = Math.max(
prev1, // skip this house
prev2 + nums[i] // rob this house
);
prev2 = prev1;
prev1 = current;
}
return prev1;
}
🔢 Decode Ways: Secret Messages!
The Spy Story
You’re a secret agent 🕵️. You received a coded message where:
- A = 1, B = 2, C = 3, … Z = 26
The message “226” could mean:
- “2-2-6” → B-B-F → “BBF”
- “22-6” → V-F → “VF”
- “2-26” → B-Z → “BZ”
How many ways can you decode “226”? Answer: 3 ways!
The Rules
- A single digit works if it’s 1-9 (not 0!)
- Two digits work if they form 10-26
graph TD A["&#39;226&#39;"] --> B["&#39;2&#39; + decode &#39;26&#39;"] A --> C["&#39;22&#39; + decode &#39;6&#39;"] B --> D["&#39;26&#39; → 1 way"] B --> E["&#39;2&#39;+&#39;6&#39; → 1 way"] C --> F["&#39;6&#39; → 1 way"]
Walk Through “226”
| Position | Digit(s) | Valid? | Ways Here |
|---|---|---|---|
| “” | - | Base | 1 |
| “2” | 2 ✅ | Yes | 1 |
| “22” | 2✅, 22✅ | Both | 1+1=2 |
| “226” | 6✅, 26✅ | Both | 2+1=3 |
Tricky Cases
- “06” → 0 ways (can’t start with 0)
- “10” → 1 way (only “10” works)
- “27” → 1 way (2-7, can’t use “27”)
- “11” → 2 ways (1-1 or 11)
The Code
public int numDecodings(String s) {
if (s.charAt(0) == '0') return 0;
int prev2 = 1; // empty string
int prev1 = 1; // first char
for (int i = 1; i < s.length(); i++) {
int current = 0;
// Single digit (1-9)
if (s.charAt(i) != '0') {
current += prev1;
}
// Two digits (10-26)
int twoDigit = Integer.parseInt(
s.substring(i-1, i+1)
);
if (twoDigit >= 10 && twoDigit <= 26) {
current += prev2;
}
prev2 = prev1;
prev1 = current;
}
return prev1;
}
🎯 The Pattern: See It Everywhere!
All four problems share the same skeleton:
// 1. Handle base cases
// 2. Keep track of prev1, prev2
// 3. For each position i:
// current = f(prev1, prev2, data[i])
// 4. Slide the window forward
// 5. Return prev1
| Problem | prev2 means… | prev1 means… | Combine how? |
|---|---|---|---|
| Fibonacci | 2 steps back | 1 step back | Add them |
| Stairs | Ways to n-2 | Ways to n-1 | Add them |
| Robber | Max at i-2 | Max at i-1 | Max choice |
| Decode | Ways at i-2 | Ways at i-1 | Conditional add |
🚀 Key Takeaways
-
Fibonacci is the foundation — Most linear DP combines 1-2 previous answers
-
Space trick — You usually only need 2 variables, not an array!
-
Ask the right question — “Where could I have come FROM?” not “Where do I go?”
-
Build trust — Solve small cases by hand first, then see the pattern
-
Same recipe, different ingredients — All these problems look different but cook the same way!
graph LR A["Identify subproblems"] --> B["Find recurrence"] B --> C["Handle base cases"] C --> D["Code it up!"] D --> E["Optimize space"]
💪 You’ve Got This!
Linear DP is like learning to ride a bike. The first few problems feel tricky, but once you see the Fibonacci pattern hiding inside, you’ll spot it everywhere!
Remember: Every expert was once a beginner who didn’t give up. Now go practice these problems until they feel as natural as counting! 🎉
