Open In App

Target Sum

Given an array arr[] of length N and an integer target. You want to build an expression out of arr[] by adding one of the symbols ‘+‘ and ‘‘ before each integer in arr[] and then concatenate all the integers. Return the number of different expressions that can be built, which evaluates to target.

Example: 



Input : N = 5, arr[] = {1, 1, 1, 1, 1}, target = 3
Output: 5
Explanation:
There are 5 ways to assign symbols to
make the sum of array 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



Input: N = 1, arr[] = {1}, target = 1
Output: 1

Target Sum using Recursion:

The problem can be solved by recursively exploring all possible ways to combine the integers in the array while adding or subtracting them to reach the target sum. At each step, there are two choices: either add the current element to the running total or subtract it.
Let’s findTotalWays(arr, i, s, target) tells us number of ways to reach target, if first i elements have been considered and current sum is s.

Recurrence Relation:

findTotalWays(arr, i, s, target) = findTotalWays(arr, i+1,s +arr[i], target) + findTotalWays(arr, i+1, s-arr[i], target)

For each element, there are 2 options.

Base case:

Below is recursive implementation of above idea.  




// C++ program to find the number of ways to calculate
// a target number using only array elements and
// addition or subtraction operator.
#include <iostream>
#include <vector>
using namespace std;
 
// Function to find the number of ways to calculate
// a target number using only array elements and
// addition or subtraction operator.
int findTotalWays(vector<int> arr, int i, int s, int target)
{
 
    // If target is reached, return 1
    if (s == target && i == arr.size())
        return 1;
 
    // If all elements are processed and
    // target is not reached, return 0
    if (i >= arr.size())
        return 0;
 
    // Return total count of two cases
    // 1. Consider current element and add it to current sum
    // target
    // 2. Consider current element and subtract it from
    // current sum.
    return findTotalWays(arr, i + 1, s + arr[i], target)
           + findTotalWays(arr, i + 1, s - arr[i], target);
}
 
// Driver Program
int main()
{
    vector<int> arr = { 1, 1, 1, 1, 1 };
 
    // target number
    int target = 3;
 
    cout << findTotalWays(arr, 0, 0, target) << endl;
 
    return 0;
}




import java.util.ArrayList;
import java.util.List;
 
public class Main {
    // Function to find the number of ways to calculate
    // a target number using only array elements and
    // addition or subtraction operator.
    static int findTotalWays(List<Integer> arr, int i, int s, int target) {
        // If target is reached, return 1
        if (s == target && i == arr.size()) {
            return 1;
        }
 
        // If all elements are processed and
        // target is not reached, return 0
        if (i >= arr.size()) {
            return 0;
        }
 
        // Return total count of two cases:
        // 1. Consider the current element and add it to the current sum target
        // 2. Consider the current element and subtract it from the current sum.
        return findTotalWays(arr, i + 1, s + arr.get(i), target)
             + findTotalWays(arr, i + 1, s - arr.get(i), target);
    }
 
    // Driver Program
    public static void main(String[] args) {
        List<Integer> arr = new ArrayList<>();
        arr.add(1);
        arr.add(1);
        arr.add(1);
        arr.add(1);
        arr.add(1);
 
        // target number
        int target = 3;
 
        System.out.println(findTotalWays(arr, 0, 0, target));
    }
}




# Function to find the number of ways to calculate
# a target number using only array elements and
# addition or subtraction operator.
def findTotalWays(arr, i, s, target):
    # If target is reached, return 1
    if s == target and i == len(arr):
        return 1
 
    # If all elements are processed and
    # target is not reached, return 0
    if i >= len(arr):
        return 0
 
    # Return total count of two cases:
    # 1. Consider the current element and add it to the current sum target
    # 2. Consider the current element and subtract it from the current sum.
    return findTotalWays(arr, i + 1, s + arr[i], target) + findTotalWays(arr, i + 1, s - arr[i], target)
 
# Driver Program
if __name__ == "__main__":
    arr = [1, 1, 1, 1, 1]
 
    # target number
    target = 3
 
    print(findTotalWays(arr, 0, 0, target))




using System;
using System.Collections.Generic;
 
class MainClass
{
    // Function to find the number of ways to calculate
    // a target number using only array elements and
    // addition or subtraction operator.
    static int FindTotalWays(List<int> arr, int i, int s, int target)
    {
        // If target is reached, return 1
        if (s == target && i == arr.Count)
            return 1;
 
        // If all elements are processed and
        // target is not reached, return 0
        if (i >= arr.Count)
            return 0;
 
        // Return the total count of two cases:
        // 1. Consider the current element and add it to the current sum target
        // 2. Consider the current element and subtract it from the current sum.
        return FindTotalWays(arr, i + 1, s + arr[i], target)
             + FindTotalWays(arr, i + 1, s - arr[i], target);
    }
 
    public static void Main(string[] args)
    {
        List<int> arr = new List<int> { 1, 1, 1, 1, 1 };
 
        // target number
        int target = 3;
 
        Console.WriteLine(FindTotalWays(arr, 0, 0, target));
    }
}




// Function to find the number of ways to calculate
// a target number using only array elements and
// addition or subtraction operator.
function findTotalWays(arr, i, s, target) {
    // If target is reached, return 1
    if (s === target && i === arr.length) {
        return 1;
    }
 
    // If all elements are processed and
    // target is not reached, return 0
    if (i >= arr.length) {
        return 0;
    }
 
    // Return total count of two cases:
    // 1. Consider the current element and add it to the current sum target
    // 2. Consider the current element and subtract it from the current sum.
    return findTotalWays(arr, i + 1, s + arr[i], target)
         + findTotalWays(arr, i + 1, s - arr[i], target);
}
 
// Driver Program
const arr = [1, 1, 1, 1, 1];
 
// target number
const target = 3;
 
console.log(findTotalWays(arr, 0, 0, target));

Output
5







Time Complexity: O(2n), where n is size of array.
Auxiliary Space: O(n) 

Target Sum using Dynamic Programming (Memoization):

The above recursive solution has Optimal Substructure and Overlapping Subproblems so Dynamic programming (Memoization) can be used to solve the problem. So, 2D array can be used to store results of previously calculated subproblems.

Follow the below steps to Implement the idea:

Below is the implementation of the above approach:




// C++ program to find the number of ways to calculate
// a target number using only array elements and
// addition or subtraction operator.
#include <iostream>
#include <vector>
using namespace std;
 
// Function to find the number of ways to calculate
// a target number using only array elements and
// addition or subtraction operator.
int findTotalWays(vector<int>& arr,
                  vector<vector<int> >& dp, int i, int s,
                  int target, int total_sum)
{
 
    // If target is reached, return 1
    if (s == target && i == arr.size())
        return 1;
 
    // If all elements are processed and
    // target is not reached, return 0
    if (i >= arr.size())
        return 0;
 
    // If the result for the current state (i, s +
    // total_sum) has already been computed,
    // return it from the DP table to avoid redundant
    // calculations.
    if (dp[i][s + total_sum] != -1)
        return dp[i][s + total_sum];
 
    // Return total count of two cases
    // 1. Consider current element and add it to current sum
    // target
    // 2. Consider current element and subtract it from
    // current sum.
    return dp[i][s + total_sum]
           = findTotalWays(arr, dp, i + 1, s + arr[i],
                           target, total_sum)
             + findTotalWays(arr, dp, i + 1, s - arr[i],
                             target, total_sum);
}
 
// Driver Program
int main()
{
    vector<int> arr = { 1, 1, 1, 1, 1 };
    int total_sum = 0;
    for (int i = 0; i < arr.size(); i++)
        total_sum += arr[i];
    // target number
    int target = 3;
    vector<vector<int> > dp(
        arr.size(), vector<int>(2 * total_sum + 1, -1));
    cout << findTotalWays(arr, dp, 0, 0, target, total_sum)
         << endl;
 
    return 0;
}




import java.util.ArrayList;
 
public class Main {
    // Function to find the number of ways to calculate
    // a target number using only array elements and
    // addition or subtraction operator.
    static int findTotalWays(ArrayList<Integer> arr,
                             int[][] dp, int i, int s,
                             int target, int totalSum)
    {
 
        // If target is reached, return 1
        if (s == target && i == arr.size())
            return 1;
 
        // If all elements are processed and
        // target is not reached, return 0
        if (i >= arr.size())
            return 0;
 
        // If the result for the current state (i, s +
        // totalSum) has already been computed,
        // return it from the DP table to avoid redundant
        // calculations.
        if (dp[i][s + totalSum] != -1)
            return dp[i][s + totalSum];
 
        // Return total count of two cases
        // 1. Consider the current element and add it to the
        // current sum
        //    to reach the target.
        // 2. Consider the current element and subtract it
        // from
        //    the current sum.
        return dp[i][s + totalSum]
            = findTotalWays(arr, dp, i + 1, s + arr.get(i),
                            target, totalSum)
              + findTotalWays(arr, dp, i + 1,
                              s - arr.get(i), target,
                              totalSum);
    }
 
    // Driver Program
    public static void main(String[] args)
    {
        ArrayList<Integer> arr = new ArrayList<>();
        arr.add(1);
        arr.add(1);
        arr.add(1);
        arr.add(1);
        arr.add(1);
 
        int totalSum = 0;
        for (int i = 0; i < arr.size(); i++)
            totalSum += arr.get(i);
 
        // Target number
        int target = 3;
 
        int[][] dp = new int[arr.size()][2 * totalSum + 1];
        for (int i = 0; i < arr.size(); i++) {
            for (int j = 0; j < 2 * totalSum + 1; j++) {
                dp[i][j] = -1;
            }
        }
 
        System.out.println(
            findTotalWays(arr, dp, 0, 0, target, totalSum));
    }
}




# Function to find the number of ways to calculate
# a target number using only array elements and
# addition or subtraction operator.
def find_total_ways(arr, dp, i, s, target, total_sum):
    # If target is reached, return 1
    if s == target and i == len(arr):
        return 1
 
    # If all elements are processed and
    # target is not reached, return 0
    if i >= len(arr):
        return 0
 
    # If the result for the current state (i, s +
    # total_sum) has already been computed,
    # return it from the DP table to avoid redundant
    # calculations.
    if dp[i][s + total_sum] != -1:
        return dp[i][s + total_sum]
 
    # Return the total count of two cases:
    # 1. Consider the current element and add it to the current sum target.
    # 2. Consider the current element and subtract it from the current sum.
    dp[i][s + total_sum] = find_total_ways(arr, dp, i + 1, s + arr[i], target, total_sum) + \
                          find_total_ways(arr, dp, i + 1, s - arr[i], target, total_sum)
     
    return dp[i][s + total_sum]
 
# Driver Program
if __name__ == "__main__":
    arr = [1, 1, 1, 1, 1]
    total_sum = sum(arr)
     
    # Target number
    target = 3
     
    # Create a DP table
    dp = [[-1] * (2 * total_sum + 1) for _ in range(len(arr))]
     
    # Calculate and print the result
    print(find_total_ways(arr, dp, 0, 0, target, total_sum))




using System;
using System.Collections.Generic;
 
class Program {
    // Function to find the number of ways to calculate
    // a target number using only array elements and
    // addition or subtraction operator.
    static int FindTotalWays(List<int> arr, int[, ] dp,
                             int i, int s, int target,
                             int totalSum)
    {
        // If target is reached, return 1
        if (s == target && i == arr.Count)
            return 1;
 
        // If all elements are processed and target is not
        // reached, return 0
        if (i >= arr.Count)
            return 0;
 
        // If the result for the current state (i, s +
        // totalSum) has already been computed, return it
        // from the DP table to avoid redundant
        // calculations.
        if (dp[i, s + totalSum] != -1)
            return dp[i, s + totalSum];
 
        // Return the total count of two cases:
        // 1. Consider the current element and add it to the
        // current sum to reach the target.
        // 2. Consider the current element and subtract it
        // from the current sum.
        return dp[i, s + totalSum]
            = FindTotalWays(arr, dp, i + 1, s + arr[i],
                            target, totalSum)
              + FindTotalWays(arr, dp, i + 1, s - arr[i],
                              target, totalSum);
    }
 
    // Driver Program
    static void Main()
    {
        List<int> arr = new List<int>{ 1, 1, 1, 1, 1 };
        int totalSum = 0;
        for (int i = 0; i < arr.Count; i++)
            totalSum += arr[i];
 
        // Target number
        int target = 3;
        int[, ] dp = new int[arr.Count, 2 * totalSum + 1];
        for (int i = 0; i < arr.Count; i++) {
            for (int j = 0; j < 2 * totalSum + 1; j++) {
                dp[i, j] = -1;
            }
        }
 
        Console.WriteLine(
            FindTotalWays(arr, dp, 0, 0, target, totalSum));
    }
}




// Function to find the number of ways to calculate
// a target number using only array elements and
// addition or subtraction operator.
function findTotalWays(arr, dp, i, s, target, totalSum) {
    // If the target is reached, return 1
    if (s === target && i === arr.length)
        return 1;
 
    // If all elements are processed and the target is not reached, return 0
    if (i >= arr.length)
        return 0;
 
    // If the result for the current state (i, s + totalSum) has already been computed,
    // return it from the DP table to avoid redundant calculations.
    if (dp[i][s + totalSum] !== -1)
        return dp[i][s + totalSum];
 
    // Return the total count of two cases:
    // 1. Consider the current element and add it to the current sum to reach the target.
    // 2. Consider the current element and subtract it from the current sum to reach the target.
    dp[i][s + totalSum] = findTotalWays(arr, dp, i + 1, s + arr[i], target, totalSum)
                      + findTotalWays(arr, dp, i + 1, s - arr[i], target, totalSum);
 
    return dp[i][s + totalSum];
}
 
// Driver Program
function main() {
    const arr = [1, 1, 1, 1, 1];
    let totalSum = 0;
    for (let i = 0; i < arr.length; i++)
        totalSum += arr[i];
 
    // Target number
    const target = 3;
 
    // Create a 2D DP table
    const dp = new Array(arr.length);
    for (let i = 0; i < arr.length; i++) {
        dp[i] = new Array(2 * totalSum + 1).fill(-1);
    }
 
    console.log(findTotalWays(arr, dp, 0, 0, target, totalSum));
}
 
main();

Output
5







Time Complexity: O(N*S), where N is size of array and S is total space.
Auxiliary Space: O(N*S) 


Article Tags :