Given an array arr[], consisting of N non-negative integers and an integer S, the task is to find the number of ways to obtain the sum S by adding or subtracting array elements.
Note: All the array elements need to be involved in generating the sum.
Examples:
Input: arr[] = {1, 1, 1, 1, 1}, S = 3
Output: 5
Explanation:
Following are the possible ways to obtain the sum S:
- -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: arr[] = {1, 2, 3, 4, 5}, S = 3
Output: 3
Explanation:
Following are the possible ways to obtain the sum S:
- -1 -2 -3 + 4 + 5 = 3
- -1 + 2 + 3 + 4 – 5 = 3
- 1 – 2 + 3 – 4 + 5 = 3
Recursive Approach: It can be observed that each array element can either be added or subtracted to obtain sum. Therefore, for each array element, recursively check for both the possibilities and increase count when sum S is obtained after reaching the end of the array.
Below is the implementation of the above approach:
C++
| // C++ program to implement// the above approach#include<bits/stdc++.h>usingnamespacestd;// Function to count the number of waysintdfs(intnums[], intS, intcurr_sum,        intindex, intn){        // Base Case: Reached the    // end of the array    if(index == n)    {                // Sum is equal to the        // required sum        if(S == curr_sum)            return1;        else            return0;    }    // Recursively check if required sum    // can be obtained by adding current    // element or by subtracting the    // current index element    returndfs(nums, S, curr_sum + nums[index],               index + 1, n) +            dfs(nums, S, curr_sum - nums[index],               index + 1, n);}// Function to call dfs() to // calculate the number of waysintfindWays(intnums[], intS, intn){     returndfs(nums, S, 0, 0, n);}// Driver Codeintmain(){    intS = 3;    intarr[] = { 1, 2, 3, 4, 5 };        intn = sizeof(arr) / sizeof(arr[0]);        intanswer = findWays(arr, S, n);        cout << (answer);    return0;}// This code is contributed by chitranayal | 
Java
| // Java Program to implement// the above approachimportjava.io.*;classGFG {    // Function to call dfs() to    // calculate the number of ways    staticintfindWays(int[] nums, intS)    {        returndfs(nums, S, 0, 0);    }    // Function to count the number of ways    staticintdfs(int[] nums, intS,                   intcurr_sum, intindex)    {        // Base Case: Reached the        // end of the array        if(index == nums.length) {            // Sum is equal to the            // required sum            if(S == curr_sum)                return1;            else                return0;        }        // Recursively check if required sum        // can be obtained by adding current        // element or by subtracting the        // current index element        returndfs(nums, S, curr_sum + nums[index],                   index + 1)            + dfs(nums, S, curr_sum - nums[index],                  index + 1);    }    // Driver Code    publicstaticvoidmain(String[] args)    {        intS = 3;        int[] arr = newint[] { 1, 2, 3, 4, 5};        intanswer = findWays(arr, S);        System.out.println(answer);    }} | 
Python3
| # Python3 program to implement# the above approach# Function to count the number of waysdefdfs(nums, S, curr_sum, index):        # Base Case: Reached the    # end of the array    if(index ==len(nums)):        # Sum is equal to the        # required sum        if(S ==curr_sum):            return1;        else:            return0;    # Recursively check if required sum    # can be obtained by adding current    # element or by subtracting the    # current index element    return(dfs(nums, S, curr_sum +nums[index],                            index +1) +            dfs(nums, S, curr_sum -nums[index],                             index +1));# Function to call dfs() to# calculate the number of waysdeffindWays(nums, S):        returndfs(nums, S, 0, 0);# Driver Codeif__name__ =='__main__':        S =3;    arr =[1, 2, 3, 4, 5];    answer =findWays(arr, S);        print(answer);# This code is contributed by amal kumar choubey | 
C#
| // C# Program to implement// the above approachusingSystem;classGFG{// Function to call dfs() to  // calculate the number of ways  staticintfindWays(int[] nums, intS)  {    returndfs(nums, S, 0, 0);  }  // Function to count the number of ways  staticintdfs(int[] nums, intS,                 intcurr_sum, intindex)  {    // Base Case: Reached the    // end of the array    if(index == nums.Length)     {      // Sum is equal to the      // required sum      if(S == curr_sum)        return1;      else        return0;    }    // Recursively check if required sum    // can be obtained by adding current    // element or by subtracting the    // current index element    returndfs(nums, S, curr_sum +                nums[index], index + 1) +              dfs(nums, S, curr_sum -                nums[index], index + 1);  }  // Driver Code  publicstaticvoidMain(String[] args)  {    intS = 3;    int[] arr = newint[] { 1, 2, 3, 4, 5 };    intanswer = findWays(arr, S);    Console.WriteLine(answer);  }}// This code is contributed by Rajput-Ji | 
Javascript
| <script>    // Javascript Program to implement     // the above approach        // Function to call dfs() to    // calculate the number of ways    functionfindWays(nums, S)    {      returndfs(nums, S, 0, 0);    }    // Function to count the number of ways    functiondfs(nums, S, curr_sum, index)    {      // Base Case: Reached the      // end of the array      if(index == nums.length)      {        // Sum is equal to the        // required sum        if(S == curr_sum)          return1;        else          return0;      }      // Recursively check if required sum      // can be obtained by adding current      // element or by subtracting the      // current index element      returndfs(nums, S, curr_sum +                 nums[index], index + 1) +               dfs(nums, S, curr_sum -                 nums[index], index + 1);    }        let S = 3;    let arr = [ 1, 2, 3, 4, 5 ];    let answer = findWays(arr, S);    document.write(answer);  </script> | 
3
Time Complexity: O(2N) 
Auxiliary Space: O(1)
Dynamic Programming Approach: The above recursive approach can be optimized by using Memoization.
Below is the implementation of the above approach:
C++
| // C++ Program to implement// the above approach#include <bits/stdc++.h>usingnamespacestd;// Function to perform the DFS to calculate the// number of waysintdfs(vector<vector<int>> memo, intnums[], intS,               intcurr_sum, intindex, intsum, intN){    // Base case: Reached the end of array    if(index == N) {        // If current sum is obtained        if(S == curr_sum)            return1;        // Otherwise        else            return0;    }    // If previously calculated    // subproblem occurred    if(memo[index][curr_sum + sum]        != INT_MIN) {        returnmemo[index][curr_sum + sum];    }    // Check if the required sum can    // be obtained by adding current    // element or by subtracting the    // current index element    intans = dfs(memo, nums, index + 1,                  curr_sum + nums[index], S, sum, N)              + dfs(memo, nums, index + 1,                    curr_sum - nums[index], S, sum, N);    // Store the count of ways    memo[index][curr_sum + sum] = ans;    returnans;}// Function to call dfs// to calculate the number of waysintfindWays(intnums[], intS, intN){    intsum = 0;    // Iterate till the length of array    for(inti = 0; i < N; i++)        sum += nums[i];    // Initialize the memorization table    vector<vector<int>> memo(N + 1, vector<int> (2 * sum + 1, INT_MIN));     returndfs(memo, nums, S, 0, 0, sum, N);}// Driver codeintmain(){    intS = 3;    intarr[] ={ 1, 2, 3, 4, 5 };    intN = sizeof(arr) / sizeof(arr[0]);    intanswer = findWays(arr, S, N);    cout << answer << endl;    return0;}// This code is contributed by divyesh072019 | 
Java
| // Java Program to implement// the above approachimportjava.io.*;importjava.util.*;classGFG {    // Function to call dfs    // to calculate the number of ways    staticintfindWays(int[] nums, intS)    {        intsum = 0;        // Iterate till the length of array        for(inti = 0; i < nums.length; i++)            sum += nums[i];        // Initialize the memorization table        int[][] memo            = newint[nums.length + 1][2* sum + 1];        for(int[] m : memo) {            Arrays.fill(m, Integer.MIN_VALUE);        }        returndfs(memo, nums, S, 0, 0, sum);    }    // Function to perform the DFS to calculate the    // number of ways    staticintdfs(int[][] memo, int[] nums, intS,                   intcurr_sum, intindex, intsum)    {        // Base case: Reached the end of array        if(index == nums.length) {            // If current sum is obtained            if(S == curr_sum)                return1;            // Otherwise            else                return0;        }        // If previously calculated        // subproblem occurred        if(memo[index][curr_sum + sum]            != Integer.MIN_VALUE) {            returnmemo[index][curr_sum + sum];        }        // Check if the required sum can        // be obtained by adding current        // element or by subtracting the        // current index element        intans = dfs(memo, nums, index + 1,                      curr_sum + nums[index], S, sum)                  + dfs(memo, nums, index + 1,                        curr_sum - nums[index], S, sum);        // Store the count of ways        memo[index][curr_sum + sum] = ans;        returnans;    }    // Driver Code    publicstaticvoidmain(String[] args)    {        intS = 3;        int[] arr = newint[] { 1, 2, 3, 4, 5};        intanswer = findWays(arr, S);        System.out.println(answer);    }} | 
Python3
| # Python3 program to implement# the above approachimportsys# Function to call dfs to # calculate the number of waysdeffindWays(nums, S):        sum=0    # Iterate till the length of array    fori inrange(len(nums)):        sum+=nums[i]    # Initialize the memorization table    memo =[[-sys.maxsize -1fori inrange(2*sum+1)]                              forj inrange(len(nums) +1)]    returndfs(memo, nums, S, 0, 0, sum)# Function to perform the DFS to calculate the# number of waysdefdfs(memo, nums, S, curr_sum, index, sum):        # Base case: Reached the end of array    if(index ==len(nums)):                # If current sum is obtained        if(S ==curr_sum):            return1        # Otherwise        else:            return0    # If previously calculated    # subproblem occurred    if(memo[index][curr_sum +sum] !=-sys.maxsize -1):        returnmemo[index][curr_sum +sum]    # Check if the required sum can    # be obtained by adding current    # element or by subtracting the    # current index element    ans =(dfs(memo, nums, index +1,                curr_sum +nums[index], S, sum) +           dfs(memo, nums, index +1,               curr_sum -nums[index], S, sum))    # Store the count of ways    memo[index][curr_sum +sum] =ans    returnans# Driver Codeif__name__ =='__main__':        S =3    arr =[ 1, 2, 3, 4, 5]    answer =findWays(arr, S)        print(answer)# This code is contributed by bgangwar59 | 
C#
| // C# program to implement// the above approachusingSystem;classGFG{// Function to call dfs// to calculate the number of waysstaticintfindWays(int[] nums, intS){    intsum = 0;    // Iterate till the length of array    for(inti = 0; i < nums.Length; i++)        sum += nums[i];    // Initialize the memorization table    int[,] memo = newint[nums.Length + 1,                              2 * sum + 1];                                  for(inti = 0; i < memo.GetLength(0); i++)    {        for(intj = 0; j < memo.GetLength(1); j++)        {            memo[i, j] = int.MinValue;        }    }    returndfs(memo, nums, S, 0, 0, sum);}// Function to perform the DFS to calculate the// number of waysstaticintdfs(int[,] memo, int[] nums, intS,               intcurr_sum, intindex, intsum){        // Base case: Reached the end of array    if(index == nums.Length)    {                // If current sum is obtained        if(S == curr_sum)            return1;        // Otherwise        else            return0;    }    // If previously calculated    // subproblem occurred    if(memo[index, curr_sum + sum] != int.MinValue)     {        returnmemo[index, curr_sum + sum];    }    // Check if the required sum can    // be obtained by adding current    // element or by subtracting the    // current index element    intans = dfs(memo, nums, index + 1,                  curr_sum + nums[index], S, sum) +               dfs(memo, nums, index + 1,                  curr_sum - nums[index], S, sum);    // Store the count of ways    memo[index, curr_sum + sum] = ans;    returnans;}// Driver CodepublicstaticvoidMain(String[] args){    intS = 3;    int[] arr = newint[] { 1, 2, 3, 4, 5 };    intanswer = findWays(arr, S);        Console.WriteLine(answer);}}// This code is contributed by Amit Katiyar | 
Javascript
| <script>// Javascript program to implement// the above approach// Function to call dfs// to calculate the number of waysfunctionfindWays(nums, S){     let sum = 0;         // Iterate till the length of array    for(let i = 0; i < nums.length; i++)        sum += nums[i];    // Initialize the memorization table    let memo = newArray([nums.length + 1][2 * sum + 1]);         for(let i = 0; i < nums.length + 1; i++)    {        memo[i] = newArray(2 * sum + 1);        for(let j = 0; j < 2 * sum + 1; j++)        {            memo[i][j] = Number.MIN_VALUE;        }    }    returndfs(memo, nums, S, 0, 0, sum);}// Function to perform the DFS to calculate// the number of waysfunctiondfs(memo, nums, S, curr_sum, index, sum){        // Base case: Reached the end of array    if(index == nums.length)     {                // If current sum is obtained        if(S == curr_sum)            return1;        // Otherwise        else            return0;    }    // If previously calculated    // subproblem occurred    if(memo[index][curr_sum + sum] !=         Number.MIN_VALUE)     {        returnmemo[index][curr_sum + sum];    }    // Check if the required sum can    // be obtained by adding current    // element or by subtracting the    // current index element    let ans = dfs(memo, nums, index + 1,                  curr_sum + nums[index], S, sum) +               dfs(memo, nums, index + 1,                  curr_sum - nums[index], S, sum);    // Store the count of ways    memo[index][curr_sum + sum] = ans;    returnans;}// Driver Codelet S = 3;let arr = [ 1, 2, 3, 4, 5 ];let answer = findWays(arr, S);document.write(answer);// This code is contributed by avanitrachhadiya2155</script> | 
3
Time Complexity: O(N * S) 
Auxiliary Space: O(N * S)
Knapsack Approach: The idea is to implement the 0/1 Knapsack problem. Follow the steps below:
- The original problem reduces to finding the number of ways to find a subset of arr[] that are all positive and the remaining elements as negative, such that their sum is equal to S.
- Therefore, the problem is to finding no of subsets from the given array having sum (S + totalSum)/2.
Below is the implementation of the above approach:
C++
| // C++ program to implement// the above approach#include <bits/stdc++.h>usingnamespacestd;// Function to call dfs// to calculate the number of waysintknapSack(intnums[], intS, intn){    intsum = 0;    for(inti = 0; i < n; i++)        sum += nums[i];    // If target + sum is odd or    // S exceeds sum    if(sum < S || -sum > -S ||       (S + sum) % 2 == 1)        // No sultion exists        return0;    intdp[(S + sum) / 2 + 1];    for(inti = 0; i <= (S + sum) / 2; i++)        dp[i] = 0;            dp[0] = 1;    for(intj = 0; j < n; j++)    {        for(inti = (S + sum) / 2;                i >= nums[j]; i--)         {            dp[i] += dp[i - nums[j]];        }    }    // Return the answer    returndp[(S + sum) / 2];}// Driver Codeintmain(){    intS = 3;    intarr[] = { 1, 2, 3, 4, 5 };    intanswer = knapSack(arr, S, 5);        cout << answer << endl;}// This code is contributed by amal kumar choubey | 
Java
| // Java Program to implement// the above approachimportjava.io.*;classGFG {    // Function to call dfs    // to calculate the number of ways    staticintknapSack(int[] nums, intS)    {        intsum = 0;        for(inti : nums)            sum += i;        // If target + sum is odd or S exceeds sum        if(sum < S || -sum > -S || (S + sum) % 2== 1)            // No sultion exists            return0;        int[] dp = newint[(S + sum) / 2+ 1];        dp[0] = 1;        for(intnum : nums) {            for(inti = dp.length - 1; i >= num; i--) {                dp[i] += dp[i - num];            }          }                   // Return the answer        returndp[dp.length - 1];    }    // Driver Code    publicstaticvoidmain(String[] args)    {        intS = 3;        int[] arr = newint[] { 1, 2, 3, 4, 5};        intanswer = knapSack(arr, S);        System.out.println(answer);    }} | 
Python3
| # Python3 Program to implement# the above approach# Function to call dfs# to calculate the number of waysdefknapSack(nums, S):    sum=0;    fori inrange(len(nums)):        sum+=nums[i];    # If target + sum is odd or S exceeds sum    if(sum< S or-sum> -S or       (S +sum) %2==1):        # No sultion exists        return0;          dp =[0]*(((S +sum) //2) +1);    dp[0] =1;    forj inrange(len(nums)):        fori inrange(len(dp) -1, nums[j] -1, -1):            dp[i] +=dp[i -nums[j]];            # Return the answer    returndp[len(dp) -1];# Driver Codeif__name__ =='__main__':    S =3;    arr =[1, 2, 3, 4, 5];    answer =knapSack(arr, S);    print(answer);# This code is contributed by Princi Singh | 
C#
| // C# Program to implement// the above approachusingSystem;classGFG{  // Function to call dfs  // to calculate the number of ways  staticintknapSack(int[] nums, intS)  {    intsum = 0;    foreach(inti innums)      sum += i;    // If target + sum is odd or S exceeds sum    if(sum < S || -sum > -S ||        (S + sum) % 2 == 1)      // No sultion exists      return0;    int[] dp = newint[(S + sum) / 2 + 1];    dp[0] = 1;    foreach(intnum innums)    {      for(inti = dp.Length - 1; i >= num; i--)       {        dp[i] += dp[i - num];      }    }    // Return the answer    returndp[dp.Length - 1];  }  // Driver Code  publicstaticvoidMain(String[] args)  {    intS = 3;    int[] arr = newint[] { 1, 2, 3, 4, 5 };    intanswer = knapSack(arr, S);    Console.WriteLine(answer);  }}// This code is contributed by Rajput-Ji | 
Javascript
| <script>    // Javascript Program to implement    // the above approach        // Function to call dfs    // to calculate the number of ways    functionknapSack(nums, S)    {        let sum = 0;        for(let i = 0; i < nums.length; i++)            sum += nums[i];         // If target + sum is odd or S exceeds sum        if(sum < S || -sum > -S || (S + sum) % 2 == 1)             // No sultion exists            return0;         let dp = newArray(parseInt((S + sum) / 2, 10) + 1);        dp.fill(0);        dp[0] = 1;         for(let num = 0; num < nums.length; num++) {            for(let i = dp.length - 1; i >= nums[num]; i--) {                dp[i] += dp[i - nums[num]];            }          }                      // Return the answer        returndp[dp.length - 1];    }        let S = 3;    let arr = [ 1, 2, 3, 4, 5 ];    let answer = knapSack(arr, S);    document.write(answer);// This code is contributed by divyeshrabadiya07.</script> | 
3
Time Complexity: O(n*(sum + S)), where sum denotes the sum of the array 
Auxiliary Space: O(S + sum)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!


 
                                    







