You are given an integer array nums
and an integer target
.
You want to build an expression out of nums by adding one of the symbols '+'
and '-'
before each integer in nums and then concatenate all the integers.
nums = [2, 1]
, you can add a '+'
before 2
and a '-'
before 1
and concatenate them to build the expression "+2-1"
.Return the number of different expressions that you can build, which evaluates to target
.
Example 1:
Input: nums = [1,1,1,1,1], target = 3 Output: 5 Explanation: There are 5 ways to assign symbols to make the sum of nums be target 3. -1 + 1 + 1 + 1 + 1 = 3 +1 - 1 + 1 + 1 + 1 = 3 +1 + 1 - 1 + 1 + 1 = 3 +1 + 1 + 1 - 1 + 1 = 3 +1 + 1 + 1 + 1 - 1 = 3
Example 2:
Input: nums = [1], target = 1 Output: 1
Constraints:
1 <= nums.length <= 20
0 <= nums[i] <= 1000
0 <= sum(nums[i]) <= 1000
-1000 <= target <= 1000
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force approach to finding a target sum involves exploring every single possible combination of pluses and minuses before each number. We then evaluate the expression to see if it matches the target. This is like trying every possible path to see which one leads to the destination.
Here's how the algorithm would work step-by-step:
def target_sum_brute_force(numbers, target):
number_of_ways = 0
def calculate_target_sum(index, current_sum):
nonlocal number_of_ways
# If we've processed all numbers, check if the sum matches the target
if index == len(numbers):
if current_sum == target:
number_of_ways += 1
return
# Explore adding the current number
calculate_target_sum(index + 1, current_sum + numbers[index])
# Explore subtracting the current number
# We explore two possibilities: add or subtract
calculate_target_sum(index + 1, current_sum - numbers[index])
# Initiate the recursive calls starting from the first number
# Initiate recursion with index 0 and a current sum of 0.
calculate_target_sum(0, 0)
return number_of_ways
The core idea is to think about the problem as exploring all possible combinations of adding or subtracting each number. However, instead of explicitly building out every combination, we can use a clever trick to count the combinations efficiently. This approach avoids redundant calculations and provides a faster solution.
Here's how the algorithm would work step-by-step:
def target_sum(numbers, target): total_sum = sum(numbers)
# The target sum is unreachable if it's out of bounds.
if (total_sum + target) % 2 != 0 or abs(target) > total_sum:
return 0
sum_of_positive_numbers = (total_sum + target) // 2
# This table stores number of subsets summing to specific values.
subset_sums = [0] * (sum_of_positive_numbers + 1)
subset_sums[0] = 1
for number in numbers:
# Iterate backwards to avoid overwriting values.
for current_sum in range(sum_of_positive_numbers, number - 1, -1):
# Accumulate counts of subsets summing to current_sum.
subset_sums[current_sum] += subset_sums[current_sum - number]
return subset_sums[sum_of_positive_numbers]
Case | How to Handle |
---|---|
Null or empty input array | Return an empty list or null to indicate no solution is possible. |
Array with a single element | Return an empty list or null since a pair requires at least two elements. |
All numbers in the array are the same, and the target is twice that number | Check if the same index is used twice by verifying the count or explicit index check. |
Array contains large positive and negative numbers resulting in potential integer overflow | Use a data type with a larger range, or check for potential overflow before performing the addition. |
No solution exists, the target sum is unachievable | Return an empty list or null to indicate that no valid pair exists. |
The array contains duplicate pairs that sum to the target | Return only distinct pairs or handle duplicates appropriately based on the problem definition. |
The target sum is zero and the array contains positive and negative numbers that can cancel out | The hashmap should accurately identify complimenting pairs. |
Large input array size impacting time and space complexity | The solution needs to be optimized, potentially using hashmaps or sorting with early termination checks, ensuring O(n) or O(n log n) time complexity. |