Perfect Sum Problem (Print all subsets with given sum)

01 Jul, 2022
Given an array of integers and a sum, the task is to print all subsets of the given array with a sum equal to a given sum.Examples: 
Input : arr[] = {2, 3, 5, 6, 8, 10}
        sum = 10
Output : 5 2 3
         2 8
         10

Input : arr[] = {1, 2, 3, 4, 5}
        sum = 10
Output : 4 3 2 1 
         5 3 2 
         5 4 1 
Asked in Tesco
This problem is mainly an extension of Subset Sum Problem. Here we not only need to find if there is a subset with the given sum but also need to print all subsets with a given sum.Like the previous post, we build a 2D array dp[][] such that dp[i][j] stores true if sum j is possible with array elements from 0 to i. After filling dp[][], we recursively traverse it from dp[n-1][sum]. For the cell being traversed, we store the path before reaching it and consider two possibilities for the element. 1) Element is included in the current path. 2) Element is not included in the current path.Whenever the sum becomes 0, we stop the recursive calls and print the current path.Below is an implementation of the above idea.
C++
Java
Python3
C#
Javascript
// C++ program to count all subsets with// given sum.#include <bits/stdc++.h>using namespace std; // dp[i][j] is going to store true if sum j is// possible with array elements from 0 to i.bool** dp; void display(const vector<int>& v){    for (int i = 0; i < v.size(); ++i)        printf("%d ", v[i]);    printf("\n");} // A recursive function to print all subsets with the// help of dp[][]. Vector p[] stores current subset.void printSubsetsRec(int arr[], int i, int sum, vector<int>& p){    // If we reached end and sum is non-zero. We print    // p[] only if arr[0] is equal to sum OR dp[0][sum]    // is true.    if (i == 0 && sum != 0 && dp[0][sum])    {        p.push_back(arr[i]);        // Display Only when Sum of elements of p is equal to sum          if (arr[i] == sum)              display(p);        return;    }     // If sum becomes 0    if (i == 0 && sum == 0)    {        display(p);        return;    }     // If given sum can be achieved after ignoring    // current element.    if (dp[i-1][sum])    {        // Create a new vector to store path        vector<int> b = p;        printSubsetsRec(arr, i-1, sum, b);    }     // If given sum can be achieved after considering    // current element.    if (sum >= arr[i] && dp[i-1][sum-arr[i]])    {        p.push_back(arr[i]);        printSubsetsRec(arr, i-1, sum-arr[i], p);    }} // Prints all subsets of arr[0..n-1] with sum 0.void printAllSubsets(int arr[], int n, int sum){    if (n == 0 || sum < 0)       return;     // Sum 0 can always be achieved with 0 elements    dp = new bool*[n];    for (int i=0; i<n; ++i)    {        dp[i] = new bool[sum + 1];        dp[i][0] = true;    }     // Sum arr[0] can be achieved with single element    if (arr[0] <= sum)       dp[0][arr[0]] = true;     // Fill rest of the entries in dp[][]    for (int i = 1; i < n; ++i)        for (int j = 0; j < sum + 1; ++j)            dp[i][j] = (arr[i] <= j) ? dp[i-1][j] ||                                       dp[i-1][j-arr[i]]                                     : dp[i - 1][j];    if (dp[n-1][sum] == false)    {        printf("There are no subsets with sum %d\n", sum);        return;    }     // Now recursively traverse dp[][] to find all    // paths from dp[n-1][sum]    vector<int> p;    printSubsetsRec(arr, n-1, sum, p);} // Driver codeint main(){    int arr[] = {1, 2, 3, 4, 5};    int n = sizeof(arr)/sizeof(arr[0]);    int sum = 10;    printAllSubsets(arr, n, sum);    return 0;}
// A Java program to count all subsets with given sum.import java.util.ArrayList;public class SubSet_sum_problem{    // dp[i][j] is going to store true if sum j is    // possible with array elements from 0 to i.    static boolean[][] dp;          static void display(ArrayList<Integer> v)    {       System.out.println(v);    }          // A recursive function to print all subsets with the    // help of dp[][]. Vector p[] stores current subset.    static void printSubsetsRec(int arr[], int i, int sum,                                         ArrayList<Integer> p)    {        // If we reached end and sum is non-zero. We print        // p[] only if arr[0] is equal to sum OR dp[0][sum]        // is true.        if (i == 0 && sum != 0 && dp[0][sum])        {            p.add(arr[i]);            display(p);            p.clear();            return;        }              // If sum becomes 0        if (i == 0 && sum == 0)        {            display(p);            p.clear();            return;        }              // If given sum can be achieved after ignoring        // current element.        if (dp[i-1][sum])        {            // Create a new vector to store path            ArrayList<Integer> b = new ArrayList<>();            b.addAll(p);            printSubsetsRec(arr, i-1, sum, b);        }              // If given sum can be achieved after considering        // current element.        if (sum >= arr[i] && dp[i-1][sum-arr[i]])        {            p.add(arr[i]);            printSubsetsRec(arr, i-1, sum-arr[i], p);        }    }          // Prints all subsets of arr[0..n-1] with sum 0.    static void printAllSubsets(int arr[], int n, int sum)    {        if (n == 0 || sum < 0)           return;              // Sum 0 can always be achieved with 0 elements        dp = new boolean[n][sum + 1];        for (int i=0; i<n; ++i)        {            dp[i][0] = true;         }              // Sum arr[0] can be achieved with single element        if (arr[0] <= sum)           dp[0][arr[0]] = true;              // Fill rest of the entries in dp[][]        for (int i = 1; i < n; ++i)            for (int j = 0; j < sum + 1; ++j)                dp[i][j] = (arr[i] <= j) ? (dp[i-1][j] ||                                           dp[i-1][j-arr[i]])                                         : dp[i - 1][j];        if (dp[n-1][sum] == false)        {            System.out.println("There are no subsets with" +                                                  " sum "+ sum);            return;        }              // Now recursively traverse dp[][] to find all        // paths from dp[n-1][sum]        ArrayList<Integer> p = new ArrayList<>();        printSubsetsRec(arr, n-1, sum, p);    }         //Driver Program to test above functions    public static void main(String args[])    {        int arr[] = {1, 2, 3, 4, 5};        int n = arr.length;        int sum = 10;        printAllSubsets(arr, n, sum);    }}//This code is contributed by Sumit Ghosh
# A Python program to count all subsets with given sum. # dp[i][j] is going to store True if sum j is# possible with array elements from 0 to i.dp = [[]] def display(v):    print(v) # A recursive function to print all subsets with the# help of dp[][]. list p[] stores current subset.def printSubsetsRec(arr, i, sum, p):       # If we reached end and sum is non-zero. We print    # p[] only if arr[0] is equal to sum OR dp[0][sum]    # is True.    if (i == 0 and sum != 0 and dp[0][sum]):        p.append(arr[i])        display(p)        p = []        return     # If sum becomes 0    if (i == 0 and sum == 0):        display(p)        p = []        return     # If given sum can be achieved after ignoring    # current element.    if (dp[i-1][sum]):        # Create a new list to store path        b = []        b.extend(p)        printSubsetsRec(arr, i-1, sum, b)     # If given sum can be achieved after considering    # current element.    if (sum >= arr[i] and dp[i-1][sum-arr[i]]):        p.append(arr[i])        printSubsetsRec(arr, i-1, sum-arr[i], p) # Prints all subsets of arr[0..n-1] with sum 0.def printAllSubsets(arr, n, sum):    if (n == 0 or sum < 0):        return     # Sum 0 can always be achieved with 0 elements    global dp    dp = [[False for i in range(sum+1)] for j in range(n)]     for i in range(n):        dp[i][0] = True     # Sum arr[0] can be achieved with single element    if (arr[0] <= sum):        dp[0][arr[0]] = True     # Fill rest of the entries in dp[][]    for i in range(1, n):        for j in range(0, sum + 1):            if (arr[i] <= j):                dp[i][j] = (dp[i-1][j] or dp[i-1][j-arr[i]])            else:                dp[i][j] = dp[i - 1][j]     if (dp[n-1][sum] == False):        println("There are no subsets with sum ", sum)        return     # Now recursively traverse dp[][] to find all    # paths from dp[n-1][sum]    p = []    printSubsetsRec(arr, n-1, sum, p) arr = [1, 2, 3, 4, 5]n = len(arr)sum = 10printAllSubsets(arr, n, sum) # This code is contributed by Lovely Jain
// A C# program to count all subsets with given sum. using System;using System.Collections.Generic; public class SubSet_sum_problem{   // dp[i][j] is going to store true if sum j is  // possible with array elements from 0 to i.  static bool[, ] dp;   static void display(List<int> v)  {    foreach(var i in v) Console.Write(i + " ");    Console.WriteLine();  }   // A recursive function to print all subsets with the  // help of dp[][]. Vector p[] stores current subset.  static void printSubsetsRec(int[] arr, int i, int sum,                              List<int> p)  {    // If we reached end and sum is non-zero. We print    // p[] only if arr[0] is equal to sum OR dp[0][sum]    // is true.    if (i == 0 && sum != 0 && dp[0, sum]) {      p.Add(arr[i]);      display(p);      p.Clear();      return;    }     // If sum becomes 0    if (i == 0 && sum == 0) {      display(p);      p.Clear();      return;    }     // If given sum can be achieved after ignoring    // current element.    if (dp[i - 1, sum]) {      // Create a new vector to store path      List<int> b = new List<int>();      b.AddRange(p);      printSubsetsRec(arr, i - 1, sum, b);    }     // If given sum can be achieved after considering    // current element.    if (sum >= arr[i] && dp[i - 1, sum - arr[i]]) {      p.Add(arr[i]);      printSubsetsRec(arr, i - 1, sum - arr[i], p);    }  }   // Prints all subsets of arr[0..n-1] with sum 0.  static void printAllSubsets(int[] arr, int n, int sum)  {    if (n == 0 || sum < 0)      return;     // Sum 0 can always be achieved with 0 elements    dp = new bool[n, sum + 1];    for (int i = 0; i < n; ++i) {      dp[i, 0] = true;    }     // Sum arr[0] can be achieved with single element    if (arr[0] <= sum)      dp[0, arr[0]] = true;     // Fill rest of the entries in dp[][]    for (int i = 1; i < n; ++i)      for (int j = 0; j < sum + 1; ++j)        dp[i, j] = (arr[i] <= j)        ? (dp[i - 1, j]           || dp[i - 1, j - arr[i]])        : dp[i - 1, j];    if (dp[n - 1, sum] == false) {      Console.WriteLine("There are no subsets with"                        + " sum " + sum);      return;    }     // Now recursively traverse dp[][] to find all    // paths from dp[n-1][sum]    List<int> p = new List<int>();    printSubsetsRec(arr, n - 1, sum, p);  }   // Driver Program to test above functions  public static void Main(string[] args)  {    int[] arr = { 1, 2, 3, 4, 5 };    int n = arr.Length;    int sum = 10;    printAllSubsets(arr, n, sum);  }} // This code is contributed by phasing17
<script>//  A Javascript program to count all subsets with given sum.//  dp[i][j] is going to store True if sum j is//  possible with array elements from 0 to i.var dp = []; function display(v){    document.write(v+"<br>");}//  A recursive function to print all subsets with the//  help of dp[][]. list p[] stores current subset.function printSubsetsRec(arr, i, sum, p){       //  If we reached end and sum is non-zero. We print    //  p[] only if arr[0] is equal to sum OR dp[0][sum]    //  is True.    if (i === 0 && sum !== 0 && dp[0][sum] !== 0){        p.push(arr[i]);        display(p);        p = [];        return;    }    //  If sum becomes 0    if (i == 0 && sum == 0){        display(p);        p = [];        return;    }    //  If given sum can be achieved after ignoring    //  current element.    if (dp[i-1][sum]){        //  Create a new list to store path        b = [...p];        printSubsetsRec(arr, i-1, sum, b);    }    //  If given sum can be achieved after considering    //  current element.    if (sum >= arr[i] && dp[i-1][sum-arr[i]]){        p.push(arr[i]);        printSubsetsRec(arr, i-1, sum-arr[i], p);    }}//  Prints all subsets of arr[0..n-1] with sum 0.function printAllSubsets(arr, n, sum){    if (n == 0 || sum < 0)        return;     //  Sum 0 can always be achieved with 0 elements    for(let i = 0; i < n; i++){        dp[i]= [];        for(let j = 0; j < sum+1; j++)            dp[i].push(false);    }      for(let i = 0; i < n; i++)        dp[i][0] = true;     //  Sum arr[0] can be achieved with single element    if (arr[0] <= sum)        dp[0][arr[0]] = true;     //  Fill rest of the entries in dp[][]     for(var i = 1; i < n; i++){         for(let j = 0; j < sum+1; j++){            if (arr[i] <= j)                dp[i][j] = (dp[i-1][j] || dp[i-1][j-arr[i]]);            else                dp[i][j] = dp[i - 1][j];        }    }    if (dp[n-1][sum] == false){        document.write("There are no subsets with sum "+ sum);        return;    }    //  Now recursively traverse dp[][] to find all    //  paths from dp[n-1][sum]    p = [];    printSubsetsRec(arr, n-1, sum, p);}arr = [1, 2, 3, 4, 5];n = arr.lengthsum = 10printAllSubsets(arr, n, sum); // This code is contributed by repakaeswaripriya.</script>
Output:
4 3 2 1
5 3 2
5 4 1
Another Approach : For each element in the array, first decide to take it or not in the subset. Define a function which will take care of all this. The function is called once in the main function. The static class fields are declared which will be operated by our function. At each call, the function checks for the condition of the fields. In our case, it checks if the current sum is equal to the given sum and accordingly increment the respective class field. If not, it makes function calls by taking all the case. So the number of function calls will be equal to the number of cases. So here, two calls are made – one by taking the element in the subset and increment the current sum and another by not taking the element.Below is the implementation :
C++
Java
Python3
Javascript
C#
// C++ code to find the number of possible subset with given sum#include <bits/stdc++.h>using namespace std; int n;int cnt;int sum; void f(int pat[], int i, int currSum){    if (currSum == sum)    {        cnt++;        return;    }     if (currSum < sum && i < n)    {        f(pat, i + 1, currSum + pat[i]);        f(pat, i + 1, currSum);    }} int main(){    cnt = 0;    n = 5;    sum = 10;     int pat[] = {2, 3, 5, 6, 8, 10};    f(pat, 0, 0);     cout << cnt << endl;    return 0;} /*This code is contributed by Nikhil Goswami (@nikhil070g) */
// Java code to find the number of// possible subset with given sumimport java.util.*;import java.lang.*;import java.io.*; class GFG {         static int count;    static int sum;    static int n;         // Driver code    public static void main (String[] args) {        count = 0;        n = 5;        sum = 10;         int[] pat = {2, 3, 5, 6, 8, 10};                 f(pat, 0, 0);                 System.out.println(count);    }         // Function to select or not the array element    // to form a subset with given sum    static void f(int[] pat, int i, int currSum) {        if (currSum == sum) {            count++;            return;        }        if (currSum < sum && i < n) {            f(pat, i+1, currSum + pat[i]);            f(pat, i+1, currSum);        }    }}
# Python code to find the number of# possible subset with given sumdef f(pat, i, currSum):    global cnt, n, sum    if (currSum == sum):        cnt += 1        return    if (currSum < sum and i < n):        f(pat, i + 1, currSum + pat[i])        f(pat, i + 1, currSum) # driver codecnt = 0n = 5sum = 10 pat = [2, 3, 5, 6, 8, 10]f(pat, 0, 0) print(cnt) # This code is contributed by shinjanpatra
<script> // JavaScript code to find the number of// possible subset with given sumlet n;let cnt;let sum; function f(pat, i, currSum){    if (currSum == sum)    {        cnt++;        return;    }     if (currSum < sum && i < n)    {        f(pat, i + 1, currSum + pat[i]);        f(pat, i + 1, currSum);    }} // driver codecnt = 0;n = 5;sum = 10; let pat = [2, 3, 5, 6, 8, 10];f(pat, 0, 0); document.write(cnt,"</br>"); // This code is contributed by shinjanpatra </script>
// C# code to find the number of// possible subset with given sum using System; class GFG {     static int count;    static int sum;    static int n;     // Driver code    public static void Main(string[] args)    {        count = 0;        n = 5;        sum = 10;         int[] pat = { 2, 3, 5, 6, 8, 10 };         f(pat, 0, 0);         Console.WriteLine(count);    }     // Function to select or not the array element    // to form a subset with given sum    static void f(int[] pat, int i, int currSum)    {        if (currSum == sum) {            count++;            return;        }        if (currSum < sum && i < n) {            f(pat, i + 1, currSum + pat[i]);            f(pat, i + 1, currSum);        }    }} // This code is contributed by phasing17
2
This article is contributed by Jas Kaur. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
shafinalakmar
nikhil070g
shinjanpatra
simmytarika5
surinderdawra388
jainlovely450
repakaeswaripriya
phasing17
Amazon
subset
Tesco
Arrays
Dynamic Programming
Amazon
Tesco
Arrays
Dynamic Programming
subset
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Maximum and minimum of an array using minimum number of comparisons
Top 50 Array Coding Problems for Interviews
Multidimensional Arrays in Java
Stack Data Structure (Introduction and Program)
Linear Search
Program for Fibonacci numbers
0-1 Knapsack Problem | DP-10
Longest Common Subsequence | DP-4
Find if there is a path between two vertices in an undirected graph
Longest Palindromic Substring | Set 1