Open In App

Print all subsets with given sum

Last Updated : 17 Mar, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Given an array arr[] of non-negative integers and an integer target. The task is to print all subsets of the array whose sum is equal to the given target.
Note: If no subset has a sum equal to target, print -1.

Examples:

Input: arr[] = [5, 2, 3, 10, 6, 8], target = 10
Output: [ [5, 2, 3], [2, 8], [10] ]
Explanation: We need to find all subsets of arr[] that sum up to target = 10.
Subset [5, 2, 3] – Sum = 5 + 2 + 3 = 10
Subset [2, 8] – Sum = 2 + 8 = 10
Subset [10] – Sum = 10

Input: arr[] = [5, 7, 8], target = 3
Output: [ [-1] ]
Explanation: There are no subsets of the array that sum up to the target 3.

Input: arr[] = [35, 2, 8, 22], target = 0
Output: [ [ ] ]
Explanation: The empty subset is the only subset with a sum of 0.

Using Recursion – O(2^n) Time and O(n) Space

The idea is to use recursion to explore all possible subsets of the given array. We either include or exclude each element while keeping track of the remaining target sum. If we reach the end of the array and the target becomes 0, we store the valid subset. Otherwise, we backtrack and explore other possibilities.

C++
// C++ Code to find subsets with sum equal 
// to target using recursion
#include <bits/stdc++.h>
using namespace std;

void findSubsets(vector<int>& arr, int index, 
                 int target,vector<int>& curr, 
                 vector<vector<int>>& result) {

    if (index >= arr.size()) {
        
        // If we reach the end and the target 
        // becomes 0, we found a valid subset
        if (target == 0) {
            result.push_back(curr);
            return;
        }
        
        // Otherwise, we return as no valid
        // subset is found
        return;
    }

    // Include current element in subset
    curr.push_back(arr[index]);
    findSubsets(arr, index + 1, 
                target - arr[index], curr, result);

    // Backtrack and exclude the current element
    curr.pop_back();
    findSubsets(arr, 
                index + 1, target, curr, result);
}

// Function to find all subsets summing to target
vector<vector<int>> perfectSum(vector<int>& arr, 
                               int target) {
                                   
    vector<vector<int>> result;
    vector<int> curr;
    findSubsets(arr, 0, target, curr, result);
    return result;
}

// Function to print subsets in required format
void print2dArray(vector<vector<int>>& arr) {
    
    if (arr.empty()) {
        
        // No valid subsets found
        cout << "-1\n"; 
        return;
    }

    int row, col;
    
    for (row = 0; row < arr.size(); row++) {
        cout << "[";
        for (col = 0; col < arr[row].size(); col++) {
            cout << arr[row][col];
            if (col != arr[row].size() - 1) {
                cout << ", ";
            }
        }
        cout << "]";
        
        if(row < arr.size() - 1) cout << ", ";
    }
}

int main() {
    vector<int> arr = {5, 2, 3, 10, 6, 8};
    int target = 10;

    // Find subsets and print result
    vector<vector<int>> result 
                        = perfectSum(arr, target);
                        
    print2dArray(result);

    return 0;
}
Java
// Java Code to find subsets with sum equal 
// to target using recursion
import java.util.ArrayList;
import java.util.List;

class GfG {
    
    static void findSubsets(int[] arr, int index, 
                            int target, List<Integer> curr, 
                            List<List<Integer>> result) {
                                
        if (index >= arr.length) {
            
            // If we reach the end and the target 
            // becomes 0, we found a valid subset
            if (target == 0) {
                result.add(new ArrayList<>(curr));
                return;
            }
            
            // Otherwise, we return as no valid
            // subset is found
            return;
        }

        // Include current element in subset
        curr.add(arr[index]);
        findSubsets(arr, index + 1, 
                    target - arr[index], curr, result);

        // Backtrack and exclude the current element
        curr.remove(curr.size() - 1);
        findSubsets(arr, 
                    index + 1, target, curr, result);
    }

    // Function to find all subsets summing to target
    static List<List<Integer>> perfectSum(int[] arr, 
                                          int target) {
                                              
        List<List<Integer>> result = new ArrayList<>();
        List<Integer> curr = new ArrayList<>();
        findSubsets(arr, 0, target, curr, result);
        return result;
    }

    // Function to print subsets in required format
    static void print2dArray(List<List<Integer>> arr) {
        
        if (arr.isEmpty()) {
            
            // No valid subsets found
            System.out.println("-1");
            return;
        }

        for (int row = 0; row < arr.size(); row++) {
            System.out.print("[");
            for (int col = 0; col < arr.get(row).size(); col++) {
                System.out.print(arr.get(row).get(col));
                if (col != arr.get(row).size() - 1) {
                    System.out.print(", ");
                }
            }
            System.out.print("]");
            
            if (row < arr.size() - 1) System.out.print(", ");
        }
    }

    public static void main(String[] args) {
        int[] arr = {5, 2, 3, 10, 6, 8};
        int target = 10;

        // Find subsets and print result
        List<List<Integer>> result = perfectSum(arr, target);
        print2dArray(result);
    }
}
Python
# Python Code to find subsets with sum equal 
# to target using recursion

def findSubsets(arr, index, target, curr, result):
    
    if index >= len(arr):
        
        # If we reach the end and the target 
        # becomes 0, we found a valid subset
        if target == 0:
            result.append(curr[:])
            return
        
        # Otherwise, we return as no valid
        # subset is found
        return

    # Include current element in subset
    curr.append(arr[index])
    findSubsets(arr, index + 1, target - arr[index], curr, result)

    # Backtrack and exclude the current element
    curr.pop()
    findSubsets(arr, index + 1, target, curr, result)

# Function to find all subsets summing to target
def perfectSum(arr, target):
    result = []
    curr = []
    findSubsets(arr, 0, target, curr, result)
    return result

# Function to print subsets in required format
def print2dArray(arr):
    
    if not arr:
        
        # No valid subsets found
        print("-1")
        return

    for row in range(len(arr)):
        print("[", end="")
        for col in range(len(arr[row])):
            print(arr[row][col], end="")
            if col != len(arr[row]) - 1:
                print(", ", end="")
        print("]", end="")
        
        if row < len(arr) - 1:
            print(", ", end="")

if __name__ == "__main__":
    arr = [5, 2, 3, 10, 6, 8]
    target = 10

    # Find subsets and print result
    result = perfectSum(arr, target)
    print2dArray(result)
C#
// C# Code to find subsets with sum equal 
// to target using recursion
using System;
using System.Collections.Generic;

class GfG {
    
    static void findSubsets(int[] arr, int index, 
                            int target, List<int> curr, 
                            List<List<int>> result) {
                                
        if (index >= arr.Length) {
            
            // If we reach the end and the target 
            // becomes 0, we found a valid subset
            if (target == 0) {
                result.Add(new List<int>(curr));
                return;
            }
            
            // Otherwise, we return as no valid
            // subset is found
            return;
        }

        // Include current element in subset
        curr.Add(arr[index]);
        findSubsets(arr, index + 1, 
                    target - arr[index], curr, result);

        // Backtrack and exclude the current element
        curr.RemoveAt(curr.Count - 1);
        findSubsets(arr, 
                    index + 1, target, curr, result);
    }

    // Function to find all subsets summing to target
    static List<List<int>> perfectSum(int[] arr, 
                                      int target) {
                                          
        List<List<int>> result = new List<List<int>>();
        List<int> curr = new List<int>();
        findSubsets(arr, 0, target, curr, result);
        return result;
    }

    // Function to print subsets in required format
    static void print2dArray(List<List<int>> arr) {
        
        if (arr.Count == 0) {
            
            // No valid subsets found
            Console.WriteLine("-1");
            return;
        }

        for (int row = 0; row < arr.Count; row++) {
            Console.Write("[");
            for (int col = 0; col < arr[row].Count; col++) {
                Console.Write(arr[row][col]);
                if (col != arr[row].Count - 1) {
                    Console.Write(", ");
                }
            }
            Console.Write("]");
            
            if (row < arr.Count - 1) Console.Write(", ");
        }
    }

    static void Main() {
        int[] arr = {5, 2, 3, 10, 6, 8};
        int target = 10;

        // Find subsets and print result
        List<List<int>> result = perfectSum(arr, target);
        print2dArray(result);
    }
}
JavaScript
// JavaScript Code to find subsets with sum equal 
// to target using recursion

function findSubsets(arr, index, target, curr, result) {
    
    if (index >= arr.length) {
        
        // If we reach the end and the target 
        // becomes 0, we found a valid subset
        if (target === 0) {
            result.push([...curr]);
            return;
        }
        
        // Otherwise, we return as no valid
        // subset is found
        return;
    }

    // Include current element in subset
    curr.push(arr[index]);
    findSubsets(arr, index + 1, target - arr[index], curr, result);

    // Backtrack and exclude the current element
    curr.pop();
    findSubsets(arr, index + 1, target, curr, result);
}

// Function to find all subsets summing to target
function perfectSum(arr, target) {
    let result = [];
    let curr = [];
    findSubsets(arr, 0, target, curr, result);
    return result;
}

// Function to print subsets in required format
function print2dArray(arr) {
    
    if (arr.length === 0) {
        
        // No valid subsets found
        console.log("-1");
        return;
    }

    let output = arr.map(subset => "[" + subset.join(", ") + "]").join(", ");
    console.log(output);
}

let arr = [5, 2, 3, 10, 6, 8];
let target = 10;

// Find subsets and print result
let result = perfectSum(arr, target);
print2dArray(result);

Output
[5, 2, 3], [2, 8], [10]

Time Complexity: O(2^n), as each element has two choices, include or exclude.
Space Complexity: O(n), due to maximum recursion depth in the worst case scenario.

Using Dynamic Programming – O(2^n) Time and O(n*target) Space

The idea is to use Dynamic Programming (DP) to determine whether a subset with the given target sum exists. We build a dp table where dp[i][j] indicates if a sum j is possible using the first i elements. Once the table is constructed, we use recursion to backtrack and find all valid subsets. If 0s are present, we handle them separately to ensure all possible combinations are included.

Steps to implement the above idea:

  • Initialize a dp table of size n × (target + 1) to track subset sum possibilities using boolean values.
  • Set dp[i][0] = true for all i since a sum of 0 is always possible with an empty subset.
  • Fill the dp table by checking whether a sum j can be formed by including or excluding arr[i].
  • If dp[n-1][target] is false, return an empty result as no valid subset exists.
  • Use recursion to backtrack through the dp table and find all subsets summing to target.
  • Maintain a temporary list to store the current subset and push valid ones to the result list.
  • Finally, print the result list in the required format, handling cases where no valid subset exists.

Below is an implementation of the above approach:

C++
// C++ Code to find subsets with sum equal to target
// using Dynamic Programming
#include <bits/stdc++.h>
using namespace std;

// Recursively finds all subsets with the given target
void findSubsets(vector<int>& arr, vector<vector<bool>>& dp, 
                 int i, int target, vector<int>& curr, 
                 vector<vector<int>>& res) {
    
    // Base case: If target becomes 0
    if (i == 0) {
        if (target == 0) res.push_back(curr);
        if (arr[0] == target) {
            curr.push_back(arr[0]);
            res.push_back(curr);
            curr.pop_back();
        }
        return;
    }

    // Exclude current element
    if (dp[i-1][target]) {
        findSubsets(arr, dp, i-1, target, curr, res);
    }
    
    // Include current element if it does not exceed target
    if (target >= arr[i] && dp[i-1][target-arr[i]]) {
        curr.push_back(arr[i]);
        findSubsets(arr, dp, i-1, target-arr[i], curr, res);
        curr.pop_back();
    }
}

// Returns all subsets with the given target sum
vector<vector<int>> perfectSum(vector<int>& arr,
                               int target) {
    int n = arr.size();
    if (n == 0 || target < 0) return {};

    // DP table to store subset sum possibilities
    vector<vector<bool>> dp(n, vector<bool>(target+1, false));

    // Correct DP initialization for handling zeroes
    dp[0][0] = true;
    if (arr[0] <= target) dp[0][arr[0]] = true;
    
    for (int i = 1; i < n; ++i) {
        for (int j = 0; j <= target; ++j) {
            dp[i][j] = dp[i-1][j] 
                       || (arr[i] <= j && dp[i-1][j-arr[i]]);
        }
    }

    // If no subsets sum to target, return empty
    if (!dp[n-1][target]) return {};

    vector<vector<int>> res;
    vector<int> curr;
    findSubsets(arr, dp, n-1, target, curr, res);
    return res;
}

// Function to print subsets in required format
void print2dArray(vector<vector<int>>& arr) {
    if (arr.empty()) {
        
        // No valid subsets found
        cout << "-1\n"; 
        return;
    }

    // Printing subsets in formatted output
    for (int row = 0; row < arr.size(); row++) {
        cout << "[";
        for (int col = arr[row].size() - 1; col >= 0 ; col--) {
            cout << arr[row][col];
            if (col != 0) {
                cout << ", ";
            }
        }
        cout << "]";
        if (row < arr.size() - 1) cout << ", ";
    }
}

// Driver function
int main() {
    vector<int> arr = {5, 2, 3, 10, 6, 8};
    int target = 10;
    vector<vector<int>> result = perfectSum(arr, target);
    print2dArray(result);
    return 0;
}
Java
// Java Code to find subsets with sum equal to target
// using Dynamic Programming
import java.util.*;

class GfG {
    
    // Recursively finds all subsets with the given target
    static void findSubsets(int[] arr, boolean[][] dp, 
                            int i, int target, List<Integer> curr, 
                            List<List<Integer>> res) {
        
        // Base case: If target becomes 0
        if (i == 0) {
            if (target == 0) res.add(new ArrayList<>(curr));
            if (arr[0] == target) {
                curr.add(arr[0]);
                res.add(new ArrayList<>(curr));
                curr.remove(curr.size() - 1);
            }
            return;
        }

        // Exclude current element
        if (dp[i-1][target]) {
            findSubsets(arr, dp, i-1, target, curr, res);
        }
        
        // Include current element if it does not exceed target
        if (target >= arr[i] && dp[i-1][target-arr[i]]) {
            curr.add(arr[i]);
            findSubsets(arr, dp, i-1, target-arr[i], curr, res);
            curr.remove(curr.size() - 1);
        }
    }

    // Returns all subsets with the given target sum
    static List<List<Integer>> perfectSum(int[] arr, int target) {
        int n = arr.length;
        if (n == 0 || target < 0) return new ArrayList<>();

        // DP table to store subset sum possibilities
        boolean[][] dp = new boolean[n][target + 1];

        // Correct DP initialization for handling zeroes
        dp[0][0] = true;
        if (arr[0] <= target) dp[0][arr[0]] = true;
        
        for (int i = 1; i < n; ++i) {
            for (int j = 0; j <= target; ++j) {
                dp[i][j] = dp[i-1][j] 
                           || (arr[i] <= j && dp[i-1][j-arr[i]]);
            }
        }

        // If no subsets sum to target, return empty
        if (!dp[n-1][target]) return new ArrayList<>();

        List<List<Integer>> res = new ArrayList<>();
        findSubsets(arr, dp, n-1, target, new ArrayList<>(), res);
        return res;
    }

    // Function to print subsets in required format
    static void print2dArray(List<List<Integer>> arr) {
        if (arr.isEmpty()) {
            
            // No valid subsets found
            System.out.println("-1"); 
            return;
        }

        // Printing subsets in formatted output
        for (int row = 0; row < arr.size(); row++) {
            System.out.print("[");
            for (int col = arr.get(row).size() - 1; col >= 0; col--) {
                System.out.print(arr.get(row).get(col));
                if (col != 0) {
                    System.out.print(", ");
                }
            }
            System.out.print("]");
            if (row < arr.size() - 1) System.out.print(", ");
        }
    }

    // Driver function
    public static void main(String[] args) {
        int[] arr = {5, 2, 3, 10, 6, 8};
        int target = 10;
        List<List<Integer>> result = perfectSum(arr, target);
        print2dArray(result);
    }
}
Python
# Python Code to find subsets with sum equal to target
# using Dynamic Programming

# Recursively finds all subsets with the given target
def findSubsets(arr, dp, i, target, curr, res):
    
    # Base case: If target becomes 0
    if i == 0:
        if target == 0:
            res.append(curr[:])
        if arr[0] == target:
            curr.append(arr[0])
            res.append(curr[:])
            curr.pop()
        return

    # Exclude current element
    if dp[i-1][target]:
        findSubsets(arr, dp, i-1, target, curr, res)
    
    # Include current element if it does not exceed target
    if target >= arr[i] and dp[i-1][target-arr[i]]:
        curr.append(arr[i])
        findSubsets(arr, dp, i-1, target-arr[i], curr, res)
        curr.pop()

# Returns all subsets with the given target sum
def perfectSum(arr, target):
    n = len(arr)
    if n == 0 or target < 0:
        return []

    # DP table to store subset sum possibilities
    dp = [[False] * (target+1) for _ in range(n)]

    # Correct DP initialization for handling zeroes
    dp[0][0] = True
    if arr[0] <= target:
        dp[0][arr[0]] = True
    
    for i in range(1, n):
        for j in range(target+1):
            dp[i][j] = dp[i-1][j] or (arr[i] <= j and dp[i-1][j-arr[i]])

    # If no subsets sum to target, return empty
    if not dp[n-1][target]:
        return []

    res = []
    curr = []
    findSubsets(arr, dp, n-1, target, curr, res)
    return res

# Function to print subsets in required format
def print2dArray(arr):
    if not arr:
        
        # No valid subsets found
        print("-1")
        return

    # Printing subsets in formatted output
    for row in range(len(arr)):
        print("[", end="")
        for col in range(len(arr[row]) - 1, -1, -1):
            print(arr[row][col], end="")
            if col != 0:
                print(", ", end="")
        print("]", end="")
        if row < len(arr) - 1:
            print(", ", end="")


if __name__ == "__main__":
    
    arr = [5, 2, 3, 10, 6, 8]
    target = 10
    
    result = perfectSum(arr, target)
    
    print2dArray(result)
C#
// C# Code to find subsets with sum equal to target
// using Dynamic Programming
using System;
using System.Collections.Generic;

class GfG {

    // Recursively finds all subsets with the given target
    static void findSubsets(int[] arr, bool[,] dp, 
                            int i, int target, List<int> curr, 
                            List<List<int>> res) {
        
        // Base case: If target becomes 0
        if (i == 0) {
            if (target == 0) res.Add(new List<int>(curr));
            if (arr[0] == target) {
                curr.Add(arr[0]);
                res.Add(new List<int>(curr));
                curr.RemoveAt(curr.Count - 1);
            }
            return;
        }

        // Exclude current element
        if (dp[i-1, target]) {
            findSubsets(arr, dp, i-1, target, curr, res);
        }
        
        // Include current element if it does not exceed target
        if (target >= arr[i] && dp[i-1, target-arr[i]]) {
            curr.Add(arr[i]);
            findSubsets(arr, dp, i-1, target-arr[i], curr, res);
            curr.RemoveAt(curr.Count - 1);
        }
    }

    // Returns all subsets with the given target sum
    static List<List<int>> perfectSum(int[] arr, int target) {
        int n = arr.Length;
        if (n == 0 || target < 0) return new List<List<int>>();

        // DP table to store subset sum possibilities
        bool[,] dp = new bool[n, target + 1];

        // Correct DP initialization for handling zeroes
        dp[0, 0] = true;
        if (arr[0] <= target) dp[0, arr[0]] = true;
        
        for (int i = 1; i < n; ++i) {
            for (int j = 0; j <= target; ++j) {
                dp[i, j] = dp[i-1, j] 
                           || (arr[i] <= j && dp[i-1, j-arr[i]]);
            }
        }

        // If no subsets sum to target, return empty
        if (!dp[n-1, target]) return new List<List<int>>();

        List<List<int>> res = new List<List<int>>();
        findSubsets(arr, dp, n-1, target, new List<int>(), res);
        return res;
    }

    // Function to print subsets in required format
    static void print2dArray(List<List<int>> arr) {
        if (arr.Count == 0) {
            
            // No valid subsets found
            Console.WriteLine("-1"); 
            return;
        }

        // Printing subsets in formatted output
        for (int row = 0; row < arr.Count; row++) {
            Console.Write("[");
            for (int col = arr[row].Count - 1; col >= 0; col--) {
                Console.Write(arr[row][col]);
                if (col != 0) {
                    Console.Write(", ");
                }
            }
            Console.Write("]");
            if (row < arr.Count - 1) Console.Write(", ");
        }
    }

    // Driver function
    static void Main() {
        int[] arr = {5, 2, 3, 10, 6, 8};
        int target = 10;
        List<List<int>> result = perfectSum(arr, target);
        print2dArray(result);
    }
}
JavaScript
// JavaScript Code to find subsets with sum equal to target
// using Dynamic Programming
function findSubsets(arr, dp, i, target, curr, res) {
    
    // Base case: If target becomes 0
    if (i === 0) {
        if (target === 0) res.push([...curr]);
        if (arr[0] === target) {
            curr.push(arr[0]);
            res.push([...curr]);
            curr.pop();
        }
        return;
    }

    // Exclude current element
    if (dp[i - 1][target]) {
        findSubsets(arr, dp, i - 1, target, curr, res);
    }

    // Include current element if it does not exceed target
    if (target >= arr[i] && dp[i - 1][target - arr[i]]) {
        curr.push(arr[i]);
        findSubsets(arr, dp, i - 1, target - arr[i], curr, res);
        curr.pop();
    }
}

function perfectSum(arr, target) {
    let n = arr.length;
    if (n === 0 || target < 0) return [];

    // DP table to store subset sum possibilities
    let dp = Array.from({ length: n }, () => Array(target + 1).fill(false));

    // Correct DP initialization for handling zeroes
    dp[0][0] = true;
    if (arr[0] <= target) dp[0][arr[0]] = true;

    for (let i = 1; i < n; ++i) {
        for (let j = 0; j <= target; ++j) {
            dp[i][j] = dp[i - 1][j] || (arr[i] <= j && dp[i - 1][j - arr[i]]);
        }
    }

    // If no subsets sum to target, return empty
    if (!dp[n - 1][target]) return [];

    let res = [];
    let curr = [];
    findSubsets(arr, dp, n - 1, target, curr, res);
    return res;
}

function print2dArray(arr) {
    if (arr.length === 0) {
        
        // No valid subsets found
        console.log("-1");
        return;
    }

    // Printing subsets in formatted output
    let output = "";
    for (let row = 0; row < arr.length; row++) {
        output += "[";
        for (let col = arr[row].length - 1; col >= 0; col--) {
            output += arr[row][col];
            if (col !== 0) {
                output += ", ";
            }
        }
        output += "]";
        if (row < arr.length - 1) output += ", ";
    }
    console.log(output);
}

// Driver Code
let arr = [5, 2, 3, 10, 6, 8];
let target = 10;
let result = perfectSum(arr, target);
print2dArray(result);

Output
[5, 2, 3], [10], [2, 8]

Time Complexity: O(2^n), as DP table filling takes O(n * target), and subset generation takes O(2^n).
Space Complexity: O(n * target), as DP table uses O(n * target) space, and recursion stack takes O(n).



Next Article

Similar Reads