Open In App

Perfect Sum Problem (Print all subsets with given sum)

Last Updated : 12 Dec, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

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

Recommended Practice

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




// 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 code
int main()
{
    int arr[] = {1, 2, 3, 4, 5};
    int n = sizeof(arr)/sizeof(arr[0]);
    int sum = 10;
    printAllSubsets(arr, n, sum);
    return 0;
}


Java




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


Python3




# 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 = 10
printAllSubsets(arr, n, sum)
 
# This code is contributed by Lovely Jain


C#




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


Javascript




<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.length
sum = 10
printAllSubsets(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 that 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 increments 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 incrementing the current sum and another by not taking the element.

Below is the implementation :

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




// Java code to find the number of
// possible subset with given sum
import 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);
        }
    }
}


Python3




# Python code to find the number of
# possible subset with given sum
def 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 code
cnt = 0
n = 5
sum = 10
 
pat = [2, 3, 5, 6, 8, 10]
f(pat, 0, 0)
 
print(cnt)
 
# This code is contributed by shinjanpatra


Javascript




<script>
 
// JavaScript code to find the number of
// possible subset with given sum
let 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 code
cnt = 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#




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


Output

2

Time Complexity: O(2n)
Auxiliary Space: O(log(n)) due to the recursion call stack.



Previous Article
Next Article

Similar Reads

Print all Perfect Numbers from an array whose sum of digits is also a Perfect Number
Given an array arr[] of size N, the task is to print all the perfect numbers from an array whose sum of digits is also a perfect number. Examples: Input: arr[] = { 3, 8, 12, 28, 6 }Output: 6Explanation: The array element arr[4] (= 6) is a perfect number. The array element arr[3] (= 28) is a perfect number but its sum of digits (= 10) is not a perfe
8 min read
Sum of all subsets whose sum is a Perfect Number from a given array
Given an array arr[] consisting of N integers, the task is to find the sum of all subsets from an array, whose sum is a Perfect Number. Examples: Input: arr[] = {5, 4, 6}Output: 6Explanation:All possible subsets from the array arr[] are:{5} ? Sum = 5{4} ? Sum = 4.{6} ? Sum = 6.{5, 4} ? Sum = 9.{5, 6} ? Sum = 11.{4, 6} ? Sum = 10.{5, 4, 6} ? Sum = 1
14 min read
Sum of subsets of all the subsets of an array | O(3^N)
Given an array arr[] of length N, the task is to find the overall sum of subsets of all the subsets of the array.Examples: Input: arr[] = {1, 1} Output: 6 All possible subsets: a) {} : 0 All the possible subsets of this subset will be {}, Sum = 0 b) {1} : 1 All the possible subsets of this subset will be {} and {1}, Sum = 0 + 1 = 1 c) {1} : 1 All t
6 min read
Sum of subsets of all the subsets of an array | O(2^N)
Given an array arr[] of length N, the task is to find the overall sum of subsets of all the subsets of the array.Examples: Input: arr[] = {1, 1} Output: 6 All possible subsets: a) {} : 0 All the possible subsets of this subset will be {}, Sum = 0 b) {1} : 1 All the possible subsets of this subset will be {} and {1}, Sum = 0 + 1 = 1 c) {1} : 1 All t
6 min read
Sum of subsets of all the subsets of an array | O(N)
Given an array arr[] of length N, the task is to find the overall sum of subsets of all the subsets of the array.Examples: Input: arr[] = {1, 1} Output: 6 All possible subsets: a) {} : 0 All the possible subsets of this subset will be {}, Sum = 0 b) {1} : 1 All the possible subsets of this subset will be {} and {1}, Sum = 0 + 1 = 1 c) {1} : 1 All t
7 min read
Divide array in two Subsets such that sum of square of sum of both subsets is maximum
Given an integer array arr[], the task is to divide this array into two non-empty subsets such that the sum of the square of the sum of both the subsets is maximum and sizes of both the subsets must not differ by more than 1.Examples: Input: arr[] = {1, 2, 3} Output: 26 Explanation: Sum of Subset Pairs are as follows (1)2 + (2 + 3)2 = 26 (2)2 + (1
6 min read
Split array into minimum number of subsets such that elements of all pairs are present in different subsets at least once
Given an array arr[] consisting of N distinct integers, the task is to find the minimum number of times the array needs to be split into two subsets such that elements of each pair are present into two different subsets at least once. Examples: Input: arr[] = { 3, 4, 2, 1, 5 } Output: 3 Explanation: Possible pairs are { (1, 2), (1, 3), (1, 4), (1,
6 min read
Check if a number is a perfect square having all its digits as a perfect square
Given an integer N, the task is to check if the given number is a perfect square having all its digits as a perfect square or not. If found to be true, then print “Yes”. Otherwise, print “No”.Examples: Input: N = 144 Output: Yes Explanation: The number 144 is a perfect square and also the digits of the number {1(= 12, 4(= 22} is also a perfect squa
11 min read
Recursive program to print all subsets with given sum
Given an array and a number, print all subsets with sum equal to given the sum.Examples: Input : arr[] = {2, 5, 8, 4, 6, 11}, sum = 13 Output : 5 8 2 11 2 5 6 Input : arr[] = {1, 5, 8, 4, 6, 11}, sum = 9 Output : 5 4 1 8 This problem is an extension of check if there is a subset with given sum. We recursively generate all subsets. We keep track of
6 min read
Partition an array of non-negative integers into two subsets such that average of both the subsets is equal
Given an array of size N. The task is to partition the given array into two subsets such that the average of all the elements in both subsets is equal. If no such partition exists print -1. Otherwise, print the partitions. If multiple solutions exist, print the solution where the length of the first subset is minimum. If there is still a tie then p
14 min read