AlgoMaster Logo

Target Sum

Last Updated: March 28, 2026

medium
4 min read

Understanding the Problem

We have an array of non-negative integers, and for each number we must assign either a + or - sign. The question is: how many sign assignments produce a total that equals the target?

This is fundamentally a counting problem over all possible subsets. Every element ends up in one of two groups: those with a + sign and those with a - sign. If we call the sum of the positive group P and the sum of the negative group N, we need P - N = target. Since every element must go to one group or the other, we also know P + N = totalSum.

That observation is the key to unlocking the most efficient approach. But let's start simple and build up to it.

Key Constraints:

  • 1 <= nums.length <= 20 --> With n up to 20, even O(2^n) is feasible. 2^20 is about 1 million, which runs comfortably within time limits.
  • 0 <= nums[i] <= 1000 and 0 <= sum(nums[i]) <= 1000 --> The total sum is bounded by 1000, which means the range of achievable sums is [-1000, 1000]. This bounded range opens the door for DP over sum values.
  • -1000 <= target <= 1000 --> Target can be negative, so we need to handle negative indices in our DP or offset them.

Approach 1: Brute Force (Recursion)

Intuition

The most direct approach is to try every possible assignment. For each element, we have two choices: add it or subtract it. We recursively explore both branches and count how many paths produce the target sum.

Think of it as a binary tree of decisions. At level 0, we decide the sign for nums[0]. At level 1, for nums[1]. And so on. Each leaf of this tree represents one complete assignment, and we check if the accumulated sum equals the target.

Algorithm

  1. Start a recursive function with index 0 and current sum 0.
  2. At each index, make two recursive calls: one adding nums[index] and one subtracting it.
  3. When the index reaches the end of the array, check if the current sum equals the target. Return 1 if it does, 0 otherwise.
  4. Sum up the counts from both branches.

Example Walkthrough

1Start: index=0, sum=0, target=3. Choose + or - for each element.
0
1
index
1
1
2
1
3
1
4
1
1/6

Code

We're exploring all 2^n sign assignments, but many different paths reach the same (index, sum) state. What if we cached the result of each state so we never solve the same subproblem twice?

Approach 2: Memoization (Top-Down DP)

Intuition

The brute force has overlapping subproblems. Multiple paths through the decision tree can arrive at the same index with the same running sum. Once we've computed the answer for a particular (index, sum) state, there's no reason to compute it again.

By adding a cache (hash map) that stores the result for each (index, sum) pair, we avoid redundant work. The number of distinct states is bounded by n (2 totalSum + 1), since the sum can range from -totalSum to +totalSum.

Algorithm

  1. Start a recursive function with index 0 and current sum 0, along with a memo dictionary.
  2. Before computing, check if (index, currentSum) is already in the memo. If so, return the cached result.
  3. At each index, make two recursive calls (add and subtract), sum their results, store in memo, and return.
  4. Base case: when index equals the array length, return 1 if sum equals target, else 0.

Example Walkthrough

1Start: backtrack(0, 0). Explore +1 branch first.
0
1
idx=0
1
1
2
1
1/7

Code

The memoization approach tracks sums in the range [-totalSum, +totalSum], but with a mathematical transformation, we can convert this into a standard subset sum problem that only deals with non-negative values.

Approach 3: Optimal (Subset Sum DP)

Intuition

Here's the mathematical insight that transforms this problem. Divide the elements into two groups: the "positive" group P (elements with a + sign) and the "negative" group N (elements with a - sign). We know:

  • P - N = target (the expression must equal target)
  • P + N = totalSum (every element is in one group)

Adding these two equations: 2P = target + totalSum, so P = (target + totalSum) / 2.

This means we need to find the number of subsets of nums that sum to (target + totalSum) / 2. That's a classic subset sum counting problem, solvable with a clean 1D DP.

There are two quick checks before we proceed: if target + totalSum is odd, no valid assignment exists (P must be an integer), so return 0. If target + totalSum is negative, it's also impossible, so return 0.

Algorithm

  1. Compute totalSum of all elements.
  2. Check if (target + totalSum) is non-negative and even. If not, return 0.
  3. Set subsetSum = (target + totalSum) / 2.
  4. Create a 1D DP array of size subsetSum + 1, initialized to 0, with dp[0] = 1 (one way to make sum 0: take nothing).
  5. For each number in nums, iterate the DP array from right to left (from subsetSum down to num), updating dp[s] += dp[s - num].
  6. Return dp[subsetSum].

Example Walkthrough

1Init: totalSum=5, subsetSum=(3+5)/2=4. dp[0]=1 (empty subset).
0
1
base
1
0
2
0
3
0
4
0
1/7

Code