CMD Guide
HomeDSADynamic Programming

Target Sum

Mechanism

Target Sum is a disguised subset-count problem: splitting the array into a '+' group P and a '-' group N means sum(P) - sum(N) = S. Since sum(P) + sum(N) = total (the array's fixed total), adding the two equations gives 2*sum(P) = S + total, so sum(P) = (S + total) / 2. The problem collapses to: count subsets of the array whose sum equals this fixed target subsetSum — exactly the 0/1 knapsack "count subsets with given sum" pattern, solved by a DP table over (index, achievable sum).

Recognize the pattern

Brute force → optimal

Brute force: try both signs for every element recursively — a binary decision tree of depth n, giving O(2^n) time, O(n) space (recursion stack). For n=20 that's ~1,000,000 leaves — survivable but wasteful, and blows up past n=30.

Optimal: reduce to count subsets summing to s = (S + total) / 2, then run the standard 0/1 knapsack counting DP: dp[sum] = number of ways to reach sum using items processed so far. This reuses overlapping subproblems that brute force recomputes from scratch.

Complexity, derived

Let total = sum of all numbers and s = (S+total)/2. The DP table has n rows (items) and s+1 columns (achievable sums 0..s). Each cell dp[i][j] is filled in O(1) from dp[i-1][j] (skip item i) and dp[i-1][j-nums[i]] (take item i) — a direct count-of-ways recurrence, not a search, so total work is exactly n * (s+1) cell fills: O(n * s) time. Space: the 2D table is O(n*s), but since row i only reads row i-1, it collapses to a single 1D array of size s+1 processed right-to-left — O(s) space. Feasibility check: if total < |S| or (S+total) is odd, s is not a non-negative integer and the answer is 0 — this must be checked before allocating the table.

Worked example

nums = {1, 1, 2, 3}, S = 1. total = 7, so s = (1+7)/2 = 4. Count subsets summing to 4. dp array indexed 0..4, dp[0]=1 initially (empty subset sums to 0), rest 0. Each row updates dp[j] += dp[j-num] for j from s down to num.

after itemdp[0]dp[1]dp[2]dp[3]dp[4]
init10000
+111000
+112100
+212221
+312233

Check the '+2' row by hand: with items {1,1,2}, only two subsets sum to 2 — {1a,1b} and {2} — so dp[2]=2 (not 3). dp[3]=2 comes from {1,2} using either 1, and dp[4]=1 from {1,1,2}. Carrying this correct row into '+3': dp[3] += dp[0] = 2+1=3, and dp[4] += dp[1] = 1+2=3. Final dp[4] = 3, matching the expected output: {+1-1-2+3}, {-1+1-2+3}, {+1+1+2-3}.

Java (1D DP, count subsets)

public int findTargetSumWays(int[] nums, int S) {
    int total = 0;
    for (int n : nums) total += n;
    if (total < Math.abs(S) || (S + total) % 2 != 0) return 0;
    int s = (S + total) / 2;
    int[] dp = new int[s + 1];
    dp[0] = 1;
    for (int num : nums) {
        for (int j = s; j >= num; j--) {
            dp[j] += dp[j - num];
        }
    }
    return dp[s];
}

The inner loop runs right-to-left so each item is only counted once per subset (0/1 knapsack, not unbounded).

Pitfalls

When to use / when not

Use the subset-sum-count DP when the array is partitioned into exactly two groups by a linear constraint and you need the number of ways — O(n*s) time/O(s) space beats brute force decisively once n exceeds ~25.

Vs. plain recursion with memoization (top-down DP on (index, remainingSum)): same asymptotic complexity, but recursion avoids computing unreachable sums outside the feasible range in sparse cases, at the cost of recursion-stack overhead and slightly worse constant factors. Prefer bottom-up 1D DP when s is reasonably small and dense; prefer memoized recursion when s is huge but the reachable-sum set is sparse.

Vs. brute-force bitmasking/DFS: acceptable only for n ≤ ~20-25 as a fallback or for verifying DP correctness on small tests; never for production-scale n.

Takeaways

Recall: Why must the inner sum loop iterate from high to low when compressing the 2D knapsack table to 1D?


Derived from the classic 0/1 knapsack subset-sum-count reduction; complexity analysis and DP formulation are original to this page.

🤖 Don't fully get this? Learn it with Claude

Stuck on Target Sum? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.

🎨 Explain it visually

Build the mental picture, not memorization.

I just read a lesson on **Target Sum** (DSA) and want to truly understand it. Explain Target Sum from first principles using ONE vivid real-world analogy and a visual mental model — draw it as ASCII art or a clear step-by-step diagram — with a concrete example using real numbers. Then ask me one question to check I got the mental picture, and wait for my reply. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🤔 Walk me through it (interactive)

Socratic — adapts to where you're stuck.

Teach me **Target Sum** interactively. Ask me ONE guiding question at a time, wait for my answer, and adapt to my confusion — build the idea with me step by step instead of explaining it all at once. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧪 Quiz me & fix my gaps

Active recall exposes what you missed.

Quiz me on **Target Sum** with 5 questions, easy to tricky, ONE at a time. Tell me if each answer is right; at the end, explain clearly what I got wrong and why. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧠 Make it stick

Intuition + hook + flashcards for long-term memory.

Help me remember **Target Sum** for the long term: give the one-sentence intuition, a memorable hook/mnemonic, a tiny worked example, and 3 active-recall flashcards (Q -> A). If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.

📝 My notes