Bird
Raised Fist0
Interview Prepdp-knapsackmediumAmazonFacebook

Target Sum

Choose your preparation mode4 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
📋
Problem

Imagine you have a list of numbers and want to assign '+' or '-' signs to each so that the total equals a target sum. How many ways can you do this?

Given an array of integers nums and an integer target, return the number of different expressions that can be built by adding '+' or '-' before each integer such that the resulting expression evaluates to target. Input: nums (list of integers), target (integer) Output: integer representing the count of valid expressions.

1 ≤ nums.length ≤ 200 ≤ nums[i] ≤ 10000 ≤ sum(nums[i]) ≤ 1000-1000 ≤ target ≤ 1000
Edge cases: nums = [0,0,0,0,0], target = 0 → 32 (all combinations of + and - count)nums = [1000], target = 1000 → 1 (only +1000 works)nums = [1], target = 2 → 0 (no way to reach 2)
</>
IDE
def findTargetSumWays(nums: list[int], target: int) -> int:public int findTargetSumWays(int[] nums, int target)int findTargetSumWays(vector<int>& nums, int target)function findTargetSumWays(nums, target)
def findTargetSumWays(nums, target):
    # Write your solution here
    pass
class Solution {
    public int findTargetSumWays(int[] nums, int target) {
        // Write your solution here
        return 0;
    }
}
#include <vector>
using namespace std;

int findTargetSumWays(vector<int>& nums, int target) {
    // Write your solution here
    return 0;
}
function findTargetSumWays(nums, target) {
    // Write your solution here
}
0/9
Common Bugs to Avoid
Wrong: 0Base case returns 0 instead of 1 when index == len(nums) and current sum == target.Change base case to return 1 if current sum equals target at recursion end.
Wrong: 1Ignoring sign assignments for zeros, counting only one way instead of 2^count_of_zeros.Branch on both + and - for zeros as well to count all combinations.
Wrong: Nonzero for impossible targetIncorrect base case or pruning allowing invalid sums to count.Return 0 when sums do not match target at recursion end.
Wrong: Wrong count due to greedy approachGreedy sign assignment misses multiple valid ways.Use DP or recursion to enumerate all sign assignments.
Wrong: TLEUsing brute force recursion without memoization for large n.Implement memoization or bottom-up DP to reduce complexity to O(n*sum).
Test Cases
t1_01basic
Input{"nums":[1,1,1,1,1],"target":3}
Expected5

There are 5 ways to assign signs to get sum 3: -1+1+1+1+1, +1-1+1+1+1, +1+1-1+1+1, +1+1+1-1+1, +1+1+1+1-1.

t1_02basic
Input{"nums":[2,3,1],"target":2}
Expected1

Only one way: -2+3+1=2. Other sign combinations do not yield target 2.

t2_01edge
Input{"nums":[],"target":0}
Expected1

Empty array with target 0 counts as one valid expression (empty sum).

t2_02edge
Input{"nums":[0,0,0,0,0],"target":0}
Expected32

Each zero can be +0 or -0, doubling ways each time: 2^5=32 ways.

t2_03edge
Input{"nums":[1000],"target":1000}
Expected1

Only +1000 matches target 1000; -1000 does not.

t3_01corner
Input{"nums":[1,2,3],"target":7}
Expected0

Target 7 cannot be formed by any combination of + or - signs on [1,2,3].

t3_02corner
Input{"nums":[1,1,1,1,1],"target":1}
Expected10

Multiple ways to assign signs to get sum 1, similar to canonical example but different target.

t3_03corner
Input{"nums":[1,2,3,4],"target":0}
Expected2

No combination of + or - signs on [1,2,3,4] sums to 0.

t4_01performance
Input{"nums":[1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10],"target":10}
⏱ Performance - must finish in 2000ms

n=20, sum(nums)=110, DP O(n*sum) ~ 2200 operations must complete within 2s.

Practice

(1/5)
1. Given the following code, what is the output when coins = [1, 2, 5] and amount = 5?
def count_ways_space_opt(coins, amount):
    dp = [0] * (amount + 1)
    dp[0] = 1
    for coin in coins:
        for w in range(coin, amount + 1):
            dp[w] += dp[w - coin]
    return dp[amount]

coins = [1, 2, 5]
amount = 5
print(count_ways_space_opt(coins, amount))
easy
A. 4
B. 7
C. 5
D. 6

Solution

  1. Step 1: Trace dp array updates for each coin

    Start dp = [1,0,0,0,0,0]. After coin=1, dp = [1,1,1,1,1,1]. After coin=2, dp = [1,1,2,2,3,3]. After coin=5, dp = [1,1,2,2,3,6].
  2. Step 2: Confirm dp[5] value

    dp[5] = 6, representing 6 ways to make amount 5 with coins [1,2,5].
  3. Final Answer:

    Option D -> Option D
  4. Quick Check:

    Manual dp tracing matches output 6 [OK]
Hint: DP accumulates counts incrementally per coin [OK]
Common Mistakes:
  • Off-by-one in dp indexing
  • Miscounting after last coin iteration
  • Confusing permutations with combinations
2. Consider the following Python function implementing the DP with bitmask tabulation approach for partitioning an array into k equal sum subsets. What is the return value when called with nums = [1, 2, 3, 4] and k = 2?
from typing import List

def canPartitionKSubsets(nums: List[int], k: int) -> bool:
    total = sum(nums)
    if total % k != 0:
        return False
    target = total // k
    n = len(nums)
    nums.sort()
    if nums[-1] > target:
        return False

    dp = [-1] * (1 << n)
    dp[0] = 0

    for mask in range(1 << n):
        if dp[mask] == -1:
            continue
        for i in range(n):
            if (mask & (1 << i)) == 0 and dp[mask] + nums[i] <= target:
                next_mask = mask | (1 << i)
                if dp[next_mask] == -1:
                    dp[next_mask] = (dp[mask] + nums[i]) % target

    return dp[(1 << n) - 1] == 0
easy
A. True
B. False
C. Raises an exception due to index error
D. Returns None

Solution

  1. Step 1: Calculate total and target

    Sum is 10, k=2, target subset sum = 5.
  2. Step 2: Trace dp updates

    DP explores subsets; for example, {1,4} and {2,3} both sum to 5, so dp[(1<<4)-1] = 0, returning True.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Partition exists: [1,4] and [2,3] [OK]
Hint: Sum divisible by k and dp final state 0 means partition possible [OK]
Common Mistakes:
  • Confusing dp array indexing or bitmask operations
  • Forgetting to check if largest element exceeds target
3. What is the time complexity of the space-optimized bottom-up 0/1 Knapsack algorithm when there are n items and the knapsack capacity is W?
medium
A. O(2^n)
B. O(n + W)
C. O(n * W)
D. O(n * log W)

Solution

  1. Step 1: Identify loops in the algorithm

    The algorithm has an outer loop over n items and an inner loop over capacities from W down to the item's weight, which can be up to W iterations.
  2. Step 2: Calculate total operations

    Multiplying the loops gives O(n * W) time complexity. Recursive brute force is exponential, and linear or logarithmic complexities are incorrect here.
  3. Final Answer:

    Option C -> Option C
  4. Quick Check:

    Nested loops over n and W -> O(n * W) [OK]
Hint: Nested loops over items and capacity -> O(n * W) [OK]
Common Mistakes:
  • Confusing recursion stack space with time complexity.
4. What is the time complexity of the space-optimized bottom-up dynamic programming solution for counting the number of ways to make change with n coins and amount W?
medium
A. O(n * W) because for each coin we iterate over all amounts up to W
B. O(n + W) because we iterate over coins and amounts separately
C. O(W^n) due to nested loops over coins and amounts
D. O(n * W) plus O(W) auxiliary space for the dp array

Solution

  1. Step 1: Identify loops and their ranges

    Outer loop runs n times (coins), inner loop runs up to W (amount), so time is O(n * W).
  2. Step 2: Consider space usage

    DP array size is W+1, so auxiliary space is O(W). Total complexity includes both time and space, but time complexity is the main focus here.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Time O(n*W) matches DP approach [OK]
Hint: Time is product of coins and amount; space is dp array size [OK]
Common Mistakes:
  • Confusing time with space complexity
  • Forgetting auxiliary space for dp array
  • Mistaking exponential complexity for DP
5. Examine the following code snippet which attempts to solve the problem. Identify the line containing the subtle bug that causes incorrect results on some inputs.
medium
A. Line 7: zeros = s.count('0')
B. Line 10: for j in range(0, n - ones + 1):
C. Line 9: for i in range(0, m - zeros + 1): # iterating forwards
D. Line 11: dp[i + zeros][j + ones] = max(dp[i + zeros][j + ones], 1 + dp[i][j])

Solution

  1. Step 1: Understand dp iteration direction

    To avoid counting the same string multiple times, dp must be updated backwards (from high to low indices).
  2. Step 2: Identify bug in iteration

    Iterating forwards over i and j causes dp states to be reused within the same iteration, leading to overcounting.
  3. Final Answer:

    Option C -> Option C
  4. Quick Check:

    Backward iteration is required for 0/1 knapsack variants [OK]
Hint: Forward iteration in 0/1 knapsack dp causes double counting [OK]
Common Mistakes:
  • Forgetting to iterate dp backwards
  • Miscounting zeros and ones