You are given an array of integers nums and an integer target.
For each number in the array, you can choose to either add or subtract it to a total sum.
nums = [1, 2], one possible sum would be "+1-2=-1".If nums=[1,1], there are two different ways to sum the input numbers to get a sum of 0: "+1-1" and "-1+1".
Return the number of different ways that you can build the expression such that the total sum equals target.
Example 1:
Input: nums = [2,2,2], target = 2
Output: 3Explanation: There are 3 different ways to sum the input numbers to get a sum of 2.+2 +2 -2 = 2+2 -2 +2 = 2-2 +2 +2 = 2
Constraints:
1 <= nums.length <= 200 <= nums[i] <= 1000-1000 <= target <= 1000
You should aim for a solution as good or better than O(n * m) time and O(n * m) space, where n is the size of the input array and m is the sum of all the elements in the array.
Try to think in terms of recursion and visualize it as a decision tree, where we have two choices at each recursion step: assigning a positive or negative sign.
We recursively iterate through the array using index i, tracking the current sum along the recursive path. Each step branches into two paths, and we sum the number of ways to reach the target. If the index i goes out of bounds, we return 1 if the current sum equals the target; otherwise, we return 0.
This approach is exponential. We can use memoization to cache recursive call results and avoid redundant calculations. A hash map or a 2D array with modifications can be used for caching. If using a 2D array, the dimensions can be (n * (2m + 1)), where n is the array size and m represents the sum of the array elements.
class Solution:
def findTargetSumWays(self, nums: List[int], target: int) -> int:
def backtrack(i, total):
if i ==len(nums):
return total == target
return (backtrack(i + 1, total + nums[i]) +
backtrack(i + 1, total - nums[i]))
return backtrack(0, 0)class Solution:
def findTargetSumWays(self, nums: List[int], target: int) -> int:
dp = {} # (index, total) -> # of ways
def backtrack(i, total):
if i == len(nums):
return 1 if total == target else 0
if (i, total) in dp:
return dp[(i, total)]
dp[(i, total)] = (backtrack(i + 1, total + nums[i]) +
backtrack(i + 1, total - nums[i]))
return dp[(i, total)]
return backtrack(0, 0)Where is the length of the array and is the sum of all the elements in the array.
class Solution:
def findTargetSumWays(self, nums: List[int], target: int) -> int:
n = len(nums)
dp = [defaultdict(int) for _ in range(n + 1)]
dp[0][0] = 1
for i in range(n):
for total, count in dp[i].items():
dp[i + 1][total + nums[i]] += count
dp[i + 1][total - nums[i]] += count
return dp[n][target]Where is the length of the array and is the sum of all the elements in the array.
class Solution:
def findTargetSumWays(self, nums: List[int], target: int) -> int:
dp = defaultdict(int)
dp[0] = 1
for num in nums:
next_dp = defaultdict(int)
for total, count in dp.items():
next_dp[total + num] += count
next_dp[total - num] += count
dp = next_dp
return dp[target]Where is the length of the array and is the sum of all the elements in the array.