InterviewPrepKit

Home / Coding / 2-D Dynamic Programming

Target Sum

medium Original ↗
Solving tips
  • Algebraic reduction is the key insight: with P the added set and N the subtracted set, sum(P)-sum(N)=target and sum(P)+sum(N)=total give sum(P)=(target+total)/2, turning this into 'count subsets summing to that value'.
  • Add the feasibility guard first: if abs(target)>total or (total+target) is odd, return 0 before dividing.
  • Then it is a counting 0/1 knapsack: dp[s] += dp[s-num]; with the 1-D array sweep s DESCENDING so each number is used at most once per row.
  • Pitfall: don't optimize away zeros — a 0 can take + or - and legitimately doubles the count, which the subset-sum formulation handles automatically. Target O(n*subset) time.

Problem

You are given an integer array nums and an integer target. You must place either a + or a - in front of every number in nums, then concatenate them into an arithmetic expression and evaluate it. Count how many distinct sign assignments make the expression evaluate exactly to target.

Each element must receive a sign, order is fixed, and two assignments are different if any single element’s sign differs.

Examples

  • nums = [1,1,1,1,1], target = 35 — you must flip exactly one number to -; there are 5 choices of which one.
  • nums = [1], target = 11 — only +1 works.
  • nums = [1], target = 20 — neither +1 nor -1 reaches 2.

Constraints

  • 1 <= len(nums) <= 20
  • 0 <= nums[i] <= 1000
  • 0 <= sum(nums) <= 1000
  • -1000 <= target <= 1000
  • With up to 20 elements there are 2^20 ≈ 10^6 sign patterns — brute force is borderline, but the bounded sum invites a knapsack-style table.

Think about it first

Hint 1 Every element is either added or subtracted. Split `nums` into the set `P` of numbers you add and the set `N` of numbers you subtract. Then `sum(P) - sum(N) = target` and `sum(P) + sum(N) = sum(nums)`.
Hint 2 Adding those two equations, `2·sum(P) = target + sum(nums)`, so `sum(P) = (target + total) / 2`. The problem becomes: how many subsets of `nums` sum to that fixed value? That is a counting knapsack.
Hint 3 Let `dp[i][s]` be the number of ways to pick from the first `i` numbers so they sum to `s`. Each new number is either taken or skipped: `dp[i][s] = dp[i-1][s] + dp[i-1][s - nums[i-1]]`. Because each row depends only on the previous row, one rolling array suffices.
Your workspace Not runnable by design — this is your interview scratchpad. Saved on this device.