Originally published on LeetCopilot Blog
Stop guessing. Learn the exact signals that tell you a problem requires DP before you waste 30 minutes on a brute-force solution.
You stare at a LeetCode problem. You know it's a Medium. You know it involves counting or optimization. But is it DP?
You waste 20 minutes trying a greedy approach. It fails test case 17. You try recursion. Stack overflow. Finally, you peek at the solution tab:
"This is a classic dynamic programming problem."
Of course it is. But how were you supposed to know that before coding?
This guide gives you the exact checklist to recognize DP problems before you start typing.
TL;DR
- DP problems have two signatures: overlapping subproblems + optimal substructure.
- Keywords to watch for: "count the number of ways," "minimum/maximum paths," "longest/shortest subsequence."
-
The recursion test: If your brute-force recursion recalculates the same
(state)multiple times, it's DP. - The greedy litmus test: If choosing the local optimum at each step doesn't guarantee the global optimum, it's likely DP.
- Common categories: Fibonacci-style sequences, grid paths, knapsack variants, substring/subsequence problems, and decision trees with "choose or skip."
The Two Essential Properties
Dynamic Programming is just "smart recursion with a cache." If a problem doesn't have these two traits, it's not DP.
Property 1: Overlapping Subproblems
When solving the big problem, you repeatedly solve the same smaller problem.
Example: Fibonacci.
- To calculate
fib(5), you needfib(4)andfib(3). - To calculate
fib(4), you needfib(3)again. - You're solving
fib(3)twice.
The Test: Can you draw a recursion tree where some nodes repeat?
If yes → Overlapping subproblems exist → DP can help.
Property 2: Optimal Substructure
The optimal solution to the problem can be built from optimal solutions to subproblems.
Example: Shortest Path.
- If the shortest path from A to C goes through B, then the path from A to B must also be the shortest possible path to B.
Counter-Example: Longest Simple Path (can't revisit nodes).
- The longest path from A to C through B might not use the longest path from A to B, because that path might block nodes needed later.
- No optimal substructure → DP doesn't work here.
Keyword Red Flags (Problem Statement Clues)
Certain phrases are almost guaranteed DP:
| Phrase | Example Problem | Why DP? |
|---|---|---|
| "Count the number of ways" | Climbing Stairs, Unique Paths | Counting paths/combinations → classic DP. |
| "Minimum/Maximum cost/path/sum" | Coin Change, Min Path Sum | Optimization with overlapping choices. |
| "Longest/Shortest subsequence" | Longest Increasing Subsequence | Subproblems overlap across indices. |
| "Can you partition/divide..." | Partition Equal Subset Sum | Decision-making with memory. |
If the problem asks for a count, min/max, or longest/shortest of something with constraints, start thinking DP.
The Recursion Smoke Test
Here's a quick field test:
- Write a brute-force recursive solution.
- Draw the recursion tree for a small input (like
n=4). - Check: Do you see the same parameters appearing multiple times?
Example: Coin Change.
-
solve(amount=11)might callsolve(10),solve(9),solve(6). -
solve(10)also callssolve(9). -
solve(9)appears twice in different branches.
→ Overlapping subproblems detected → Add memoization (DP).
If every subproblem is unique, it's not DP—it's just recursion (like tree traversal).
Common DP Problem Archetypes
1. Fibonacci-Style Sequences
-
Pattern:
dp[i]depends ondp[i-1],dp[i-2], etc. - Examples: Climbing Stairs, House Robber, Decode Ways.
2. Grid Traversal
-
Pattern:
dp[row][col]depends on cells above or to the left. - Examples: Unique Paths, Minimum Path Sum, Dungeon Game.
3. Knapsack Variants
- Pattern: For each item, decide "take it or leave it."
- Examples: 0/1 Knapsack, Partition Equal Subset Sum, Target Sum.
4. Substring/Subsequence
-
Pattern:
dp[i][j]represents solution for substring from indexitoj. - Examples: Longest Palindromic Substring, LCS, Edit Distance.
5. Decision Trees (Choose or Skip)
- Pattern: At each element, you can include it or exclude it.
- Examples: Coin Change, Combination Sum, Word Break.
When NOT to Use DP
1. Greedy Works
Some optimization problems have a "greedy choice property" where the local optimum is always correct.
- Example: Activity Selection, Jump Game (sometimes).
- Test: Does picking the best option at each step guarantee the best overall result? If yes, use greedy.
2. No Overlapping Subproblems
If every recursive call is unique, caching doesn't help.
- Example: Full permutations, full combinations (no pruning).
3. NP-Complete Problems Without Structure
Some problems (like Traveling Salesman on arbitrary graphs) don't have efficient DP solutions.
The Step-by-Step Recognition Flow
When you read a problem, follow this mental checklist:
- Does it ask for count/min/max/longest? → +1 DP point.
- Can I frame it recursively? → +1 DP point.
- Do subproblems overlap? → +1 DP point.
- Does a greedy approach fail? → +1 DP point.
If you score 3+ points, it's almost certainly DP.
How to Build Confidence in Recognition
You don't get better at recognizing DP by reading theory. You get better by:
- Solving 20+ classic DP problems (Blind 75, Grind 75).
- Labeling problems as you solve them: "This is a grid DP." "This is a knapsack variant."
- Re-solving problems after a week to test if you can identify the pattern again.
Tools like LeetCopilot's Study Mode can help by generating flashcards that ask you to identify the pattern from the problem statement alone, before you even write code.
FAQ
Q: Can a problem be DP and Greedy?
A: Rarely. Some problems (like Jump Game II) can be solved with both, but usually one approach is clearly better.
Q: What if I'm not sure?
A: Start with a brute-force recursive solution. If it times out and you see repeated calls, memoize it. That's DP.
Q: Is DP always the fastest solution?
A: Not always. Sometimes a greedy or optimized BFS is faster. But DP is often the easiest to reason about once you see the structure.
Q: How do I know the state dimensions?
A: That's the hardest part of DP. Ask: "What changes between subproblems?" If it's one index, use 1D DP. If it's two indices or (index, remaining capacity), use 2D DP.
Q: Should I start with top-down or bottom-up?
A: Top-down (memoization) is easier to write initially. Bottom-up (tabulation) can be more efficient and is preferred in interviews for clarity.
Conclusion
Recognizing DP isn't magic. It's pattern matching.
- Look for optimization or counting queries.
- Check for overlapping subproblems in your recursion tree.
- Confirm that optimal substructure exists.
With practice, you'll be able to read "Find the number of ways to..." and immediately think: "Ah, DP. 1D array, probably Fibonacci-style."
That's when LeetCode stops feeling like guesswork and starts feeling like systematic problem-solving.
If you're looking for an AI assistant to help you master LeetCode patterns and prepare for coding interviews, check out LeetCopilot.
Top comments (0)