DP Intuition: Overlapping Subproblems
Lesson 37Advanced58 minAssessment-backed

DP Intuition: Overlapping Subproblems

Recognize when recursion repeats the same work and convert repeated decisions into reusable answers.

What you will be able to do

Identify overlapping subproblems and optimal substructure.
Explain why naive recursion explodes on Fibonacci-style and path-counting problems.
Use memoization to cache repeated subproblem answers.
Connect DP to pricing, routing, recommendation, planning, and allocation systems.
Avoid using DP when subproblems are not reusable.

Dynamic programming is not magic. It is disciplined reuse. When the same question appears many times inside a recursive decision tree, store the answer once and reuse it.

Repeated Work Is the Signal

Naive recursion often branches into the same smaller questions again and again. DP begins when you can name the repeated subproblem clearly: not the whole problem, but the exact state that determines an answer.

Recursive tree showing repeated subproblems
DP compresses a repeated recursion tree into a set of unique states.

Scenario: Pricing Plan Optimization

A subscription platform evaluates ways to apply discounts over a sequence of months. If many choices lead to the same month index and remaining credits, recomputing every suffix is wasteful. Cache the answer for each state.

QuestionDP signalState example
Can decisions be decomposed?Optimal substructurebest answer from index i
Do branches rejoin?Overlapping subproblemssame i and budget appear again
Can state summarize history?Reusable state(index, remainingCredits)
Is answer deterministic for state?Cacheable resultsame inputs return same best value
Memo cache maps state to answer
Memoization is a lookup table for previously solved states.

Same Pattern in Java, Python, and JavaScript

Climbing stairs is the simplest DP: ways(n) depends on ways(n-1) and ways(n-2), and those answers repeat.

import java.util.*;

class ClimbingStairsMemo {
    static int climb(int n) {
        return ways(n, new HashMap<>());
    }

    static int ways(int n, Map<Integer, Integer> memo) {
        if (n <= 2) return n;
        if (memo.containsKey(n)) return memo.get(n);
        int answer = ways(n - 1, memo) + ways(n - 2, memo);
        memo.put(n, answer);
        return answer;
    }
}

Assessment trap

Do not say DP just because a problem is hard. Name the state, recurrence, base case, and why subproblems repeat.

Interview signalFrequently Asked Interview Questions

These are canonical interview patterns for this topic, phrased as concrete problem statements. They avoid vague theory questions and prepare you for the exact reasoning interviewers expect: invariant, edge cases, complexity, and trade-off.

  • Return the number of ways to climb n stairs taking 1 or 2 steps.
  • Given cost per step, return the minimum cost to reach the top.
  • Count ways to decode a digit string where 1-26 map to letters.

Production practiceCompany-Style Practice Examples

These are not claimed as exact company-specific questions. They are the interview patterns repeatedly used by product companies to test whether you can move from brute force to a defensible implementation.

ExampleBrute-force approachStronger solutionProduction notes
Pricing plannerRecompute every discount suffix recursively.Cache answer by month and remaining credits.State key must include every constraint that changes the answer.
Checkout path countEnumerate all paths through a flow.Reuse ways from each step/state.DP applies only if future answer depends on summarized state.
Decode campaign codesTry every split without cache.Memoize by index in the string.Repeated suffixes dominate runtime.

Solved modelInterview Question Solutions

Question 1: Climbing Stairs

Return the number of ways to climb n stairs taking 1 or 2 steps. This is the canonical overlap problem. Memoization turns repeated recursion into one answer per n.

import java.util.*;

class ClimbingStairsMemo {
    static int climb(int n) {
        return ways(n, new HashMap<>());
    }

    static int ways(int n, Map<Integer, Integer> memo) {
        if (n <= 2) return n;
        if (memo.containsKey(n)) return memo.get(n);
        int answer = ways(n - 1, memo) + ways(n - 2, memo);
        memo.put(n, answer);
        return answer;
    }
}

Question 2: Min Cost Climbing Stairs

Given cost per step, return the minimum cost to reach the top. State is minimum cost to reach each position. Transition comes from one or two steps behind.

class MinCostClimb { static int minCost(int[] cost) { int two = 0, one = 0; for (int i = 2; i <= cost.length; i++) { int cur = Math.min(one + cost[i - 1], two + cost[i - 2]); two = one; one = cur; } return one; } }

Question 3: Decode Ways

Count ways to decode a digit string where 1-26 map to letters. State is ways from index i. A valid one-digit or two-digit token moves the index forward.

class DecodeWays { static int numDecodings(String s) { int n=s.length(); int[] dp=new int[n+1]; dp[n]=1; for(int i=n-1;i>=0;i--){ if(s.charAt(i)=='0') continue; dp[i]=dp[i+1]; if(i+1<n && Integer.parseInt(s.substring(i,i+2))<=26) dp[i]+=dp[i+2]; } return dp[0]; } }

Solved modelWorked Interview Answer

Solve climbing stairs with memoization and explain why caching changes the cost. The naive recursion repeats ways(n-1), ways(n-2), and lower states many times. Memoization solves each n once, reducing exponential branching to O(n) states.

import java.util.*;

class ClimbingStairsMemo {
    static int climb(int n) {
        return ways(n, new HashMap<>());
    }

    static int ways(int n, Map<Integer, Integer> memo) {
        if (n <= 2) return n;
        if (memo.containsKey(n)) return memo.get(n);
        int answer = ways(n - 1, memo) + ways(n - 2, memo);
        memo.put(n, answer);
        return answer;
    }
}

Hands-on drillTry It Yourself

Practice task

Draw the recursion tree for climb(5). Circle repeated subproblems and list the unique states.

Failure patternsCommon Mistakes to Avoid

  • Calling every recursion DP.
  • Not naming the state.
  • Caching with an incomplete key.
  • Ignoring base cases.
  • Using DP when branches never overlap.

Execution guardrailQuick-Start Checklist

  • Find repeated subproblems.
  • Name state precisely.
  • Define recurrence.
  • Define base cases.
  • Decide memo or table.
  • State number of unique states.

Recall drillKnowledge Check

QuestionStrong answer
What is overlapping subproblem?The same state is solved multiple times.
What is optimal substructure?An optimal answer can be built from optimal subanswers.
What does memoization store?Answer for a state.

VocabularyKey Terms

TermMeaning
StateInformation that uniquely defines a subproblem.
RecurrenceFormula connecting state to smaller states.
MemoCache of solved states.
Base caseKnown answer that stops recursion.

Next practiceFurther Reading

  • Practice Fibonacci, climbing stairs, min cost climbing stairs, and decode ways.
  • Compare recursion tree with memo cache.
  • Review recursion before complex DP.