Count of Ways to obtain given Sum from the given Array elements

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:
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:
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++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to implement
// the above approach
#include<bits/stdc++.h>
using namespace std;
 
// Function to count the number of ways
int dfs(int nums[], int S, int curr_sum,
        int index, int n)
{
     
    // Base Case: Reached the
    // end of the array
    if (index == n)
    {
         
        // Sum is equal to the
        // required sum
        if (S == curr_sum)
            return 1;
        else
            return 0;
    }
 
    // 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, n) +
           dfs(nums, S, curr_sum - nums[index],
               index + 1, n);
}
 
// Function to call dfs() to
// calculate the number of ways
int findWays(int nums[], int S, int n)
{
    return dfs(nums, S, 0, 0, n);
}
 
// Driver Code
int main()
{
    int S = 3;
    int arr[] = { 1, 2, 3, 4, 5 };
     
    int n = sizeof(arr) / sizeof(arr[0]);
     
    int answer = findWays(arr, S, n);
     
    cout << (answer);
    return 0;
}
 
// This code is contributed by chitranayal

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java Program to implement
// the above approach
import java.io.*;
 
class GFG {
 
    // Function to call dfs() to
    // calculate the number of ways
    static int findWays(int[] nums, int S)
    {
        return dfs(nums, S, 0, 0);
    }
 
    // Function to count the number of ways
    static int dfs(int[] nums, int S,
                   int curr_sum, int index)
    {
        // Base Case: Reached the
        // end of the array
        if (index == nums.length) {
 
            // Sum is equal to the
            // required sum
            if (S == curr_sum)
                return 1;
            else
                return 0;
        }
 
        // 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);
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int S = 3;
        int[] arr = new int[] { 1, 2, 3, 4, 5 };
        int answer = findWays(arr, S);
        System.out.println(answer);
    }
}

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program to implement
# the above approach
 
# Function to count the number of ways
def dfs(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):
            return 1;
        else:
            return 0;
 
    # 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 ways
def findWays(nums, S):
     
    return dfs(nums, S, 0, 0);
 
# Driver Code
if __name__ == '__main__':
     
    S = 3;
    arr = [1, 2, 3, 4, 5];
    answer = findWays(arr, S);
     
    print(answer);
 
# This code is contributed by amal kumar choubey

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# Program to implement
// the above approach
using System;
class GFG{
// Function to call dfs() to
  // calculate the number of ways
  static int findWays(int[] nums, int S)
  {
    return dfs(nums, S, 0, 0);
  }
 
  // Function to count the number of ways
  static int dfs(int[] nums, int S,
                 int curr_sum, int index)
  {
    // Base Case: Reached the
    // end of the array
    if (index == nums.Length)
    {
 
      // Sum is equal to the
      // required sum
      if (S == curr_sum)
        return 1;
      else
        return 0;
    }
 
    // 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);
  }
 
  // Driver Code
  public static void Main(String[] args)
  {
    int S = 3;
    int[] arr = new int[] { 1, 2, 3, 4, 5 };
    int answer = findWays(arr, S);
    Console.WriteLine(answer);
  }
}
 
// This code is contributed by Rajput-Ji

chevron_right


Output: 

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:

Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java Program to implement
// the above approach
import java.io.*;
import java.util.*;
 
class GFG {
 
    // Function to call dfs
    // to calculate the number of ways
    static int findWays(int[] nums, int S)
    {
        int sum = 0;
 
        // Iterate till the length of array
        for (int i = 0; i < nums.length; i++)
            sum += nums[i];
 
        // Initialize the memorization table
        int[][] memo
            = new int[nums.length + 1][2 * sum + 1];
 
        for (int[] m : memo) {
            Arrays.fill(m, Integer.MIN_VALUE);
        }
 
        return dfs(memo, nums, S, 0, 0, sum);
    }
 
    // Function to perform the DFS to calculate the
    // number of ways
    static int dfs(int[][] memo, int[] nums, int S,
                   int curr_sum, int index, int sum)
    {
        // Base case: Reached the end of array
        if (index == nums.length) {
 
            // If current sum is obtained
            if (S == curr_sum)
                return 1;
 
            // Otherwise
            else
                return 0;
        }
 
        // If previously calculated
        // subproblem occurred
        if (memo[index][curr_sum + sum]
            != Integer.MIN_VALUE) {
            return memo[index][curr_sum + sum];
        }
 
        // Check if the required sum can
        // be obtained by adding current
        // element or by subtracting the
        // current index element
        int 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;
 
        return ans;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int S = 3;
        int[] arr = new int[] { 1, 2, 3, 4, 5 };
        int answer = findWays(arr, S);
        System.out.println(answer);
    }
}

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program to implement
# the above approach
import sys
 
# Function to call dfs to
# calculate the number of ways
def findWays(nums, S):
     
    sum = 0
 
    # Iterate till the length of array
    for i in range(len(nums)):
        sum += nums[i]
 
    # Initialize the memorization table
    memo = [[-sys.maxsize - 1 for i in range(2 * sum + 1)]
                              for j in range(len(nums) + 1)]
 
    return dfs(memo, nums, S, 0, 0, sum)
 
# Function to perform the DFS to calculate the
# number of ways
def dfs(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):
            return 1
 
        # Otherwise
        else:
            return 0
 
    # If previously calculated
    # subproblem occurred
    if (memo[index][curr_sum + sum] != -sys.maxsize - 1):
        return memo[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
 
    return ans
 
# Driver Code
if __name__ == '__main__':
     
    S = 3
    arr = [ 1, 2, 3, 4, 5 ]
    answer = findWays(arr, S)
     
    print(answer)
 
# This code is contributed by bgangwar59

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to implement
// the above approach
using System;
 
class GFG{
 
// Function to call dfs
// to calculate the number of ways
static int findWays(int[] nums, int S)
{
    int sum = 0;
 
    // Iterate till the length of array
    for(int i = 0; i < nums.Length; i++)
        sum += nums[i];
 
    // Initialize the memorization table
    int[,] memo = new int[nums.Length + 1,
                              2 * sum + 1];
                               
    for(int i = 0; i < memo.GetLength(0); i++)
    {
        for(int j = 0; j < memo.GetLength(1); j++)
        {
            memo[i, j] = int.MinValue;
        }
    }
    return dfs(memo, nums, S, 0, 0, sum);
}
 
// Function to perform the DFS to calculate the
// number of ways
static int dfs(int[,] memo, int[] nums, int S,
               int curr_sum, int index, int sum)
{
     
    // Base case: Reached the end of array
    if (index == nums.Length)
    {
         
        // If current sum is obtained
        if (S == curr_sum)
            return 1;
 
        // Otherwise
        else
            return 0;
    }
 
    // If previously calculated
    // subproblem occurred
    if (memo[index, curr_sum + sum] != int.MinValue)
    {
        return memo[index, curr_sum + sum];
    }
 
    // Check if the required sum can
    // be obtained by adding current
    // element or by subtracting the
    // current index element
    int 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;
 
    return ans;
}
 
// Driver Code
public static void Main(String[] args)
{
    int S = 3;
    int[] arr = new int[] { 1, 2, 3, 4, 5 };
    int answer = findWays(arr, S);
     
    Console.WriteLine(answer);
}
}
 
// This code is contributed by Amit Katiyar

chevron_right


Output: 

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++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to implement
// the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to call dfs
// to calculate the number of ways
int knapSack(int nums[], int S, int n)
{
    int sum = 0;
    for(int i = 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
        return 0;
 
    int dp[(S + sum) / 2 + 1];
    for(int i = 0; i <= (S + sum) / 2; i++)
        dp[i] = 0;
         
    dp[0] = 1;
 
    for(int j = 0; j < n; j++)
    {
        for(int i = (S + sum) / 2;
                i >= nums[j]; i--)
        {
            dp[i] += dp[i - nums[j]];
        }
    }
 
    // Return the answer
    return dp[(S + sum) / 2];
}
 
// Driver Code
int main()
{
    int S = 3;
    int arr[] = { 1, 2, 3, 4, 5 };
    int answer = knapSack(arr, S, 5);
     
    cout << answer << endl;
}
 
// This code is contributed by amal kumar choubey

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java Program to implement
// the above approach
import java.io.*;
 
class GFG {
 
    // Function to call dfs
    // to calculate the number of ways
    static int knapSack(int[] nums, int S)
    {
        int sum = 0;
        for (int i : nums)
            sum += i;
 
        // If target + sum is odd or S exceeds sum
        if (sum < S || -sum > -S || (S + sum) % 2 == 1)
 
            // No sultion exists
            return 0;
 
        int[] dp = new int[(S + sum) / 2 + 1];
        dp[0] = 1;
 
        for (int num : nums) {
            for (int i = dp.length - 1; i >= num; i--) {
                dp[i] += dp[i - num];
            }
          }
       
      
 
        // Return the answer
        return dp[dp.length - 1];
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int S = 3;
        int[] arr = new int[] { 1, 2, 3, 4, 5 };
        int answer = knapSack(arr, S);
        System.out.println(answer);
    }
}

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 Program to implement
# the above approach
 
# Function to call dfs
# to calculate the number of ways
def knapSack(nums, S):
    sum = 0;
    for i in range(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
        return 0;
       
    dp = [0]*(((S + sum) // 2) + 1);
    dp[0] = 1;
    for j in range(len(nums)):
        for i in range(len(dp) - 1, nums[j] - 1, -1):
            dp[i] += dp[i - nums[j]];
         
    # Return the answer
    return dp[len(dp) - 1];
 
# Driver Code
if __name__ == '__main__':
    S = 3;
    arr = [1, 2, 3, 4, 5 ];
    answer = knapSack(arr, S);
    print(answer);
 
# This code is contributed by Princi Singh

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# Program to implement
// the above approach
using System;
class GFG{
 
  // Function to call dfs
  // to calculate the number of ways
  static int knapSack(int[] nums, int S)
  {
    int sum = 0;
    foreach (int i in nums)
      sum += i;
 
    // If target + sum is odd or S exceeds sum
    if (sum < S || -sum > -S ||
       (S + sum) % 2 == 1)
 
      // No sultion exists
      return 0;
 
    int[] dp = new int[(S + sum) / 2 + 1];
    dp[0] = 1;
 
    foreach (int num in nums)
    {
      for (int i = dp.Length - 1; i >= num; i--)
      {
        dp[i] += dp[i - num];
      }
    }
 
    // Return the answer
    return dp[dp.Length - 1];
  }
 
  // Driver Code
  public static void Main(String[] args)
  {
    int S = 3;
    int[] arr = new int[] { 1, 2, 3, 4, 5 };
    int answer = knapSack(arr, S);
    Console.WriteLine(answer);
  }
}
 
// This code is contributed by Rajput-Ji

chevron_right


Output: 

3







 

Time Complexity: O(n*(sum + S)), where sum denotes the sum of the array 
Auxiliary Space: O(S + sum)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up

Recommended Posts:


Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.