 Open in App
Not now

# Find all distinct subset (or subsequence) sums of an array

• Difficulty Level : Medium
• Last Updated : 27 Jan, 2023

Given a set of integers, find a distinct sum that can be generated from the subsets of the given sets and print them in increasing order. It is given that sum of array elements is small.

Examples:

```Input  : arr[] = {1, 2, 3}
Output : 0 1 2 3 4 5 6
Distinct subsets of given set are
{}, {1}, {2}, {3}, {1,2}, {2,3},
{1,3} and {1,2,3}.  Sums of these
subsets are 0, 1, 2, 3, 3, 5, 4, 6
After removing duplicates, we get
0, 1, 2, 3, 4, 5, 6

Input : arr[] = {2, 3, 4, 5, 6}
Output : 0 2 3 4 5 6 7 8 9 10 11 12
13 14 15 16 17 18 20

Input : arr[] = {20, 30, 50}
Output : 0 20 30 50 70 80 100```

The naive solution for this problem is to generate all the subsets, store their sums in a hash set and finally print all keys from the hash set.

## C++

 `// C++ program to print distinct subset sums of``// a given array.``#include``using` `namespace` `std;` `// sum denotes the current sum of the subset``// currindex denotes the index we have reached in``// the given array``void` `distSumRec(``int` `arr[], ``int` `n, ``int` `sum,``                ``int` `currindex, unordered_set<``int``> &s)``{``    ``if` `(currindex > n)``        ``return``;` `    ``if` `(currindex == n)``    ``{``        ``s.insert(sum);``        ``return``;``    ``}` `    ``distSumRec(arr, n, sum + arr[currindex],``                            ``currindex+1, s);``    ``distSumRec(arr, n, sum, currindex+1, s);``}` `// This function mainly calls recursive function``// distSumRec() to generate distinct sum subsets.``// And finally prints the generated subsets.``void` `printDistSum(``int` `arr[], ``int` `n)``{``    ``unordered_set<``int``> s;``    ``distSumRec(arr, n, 0, 0, s);` `    ``// Print the result``    ``for` `(``auto` `i=s.begin(); i!=s.end(); i++)``        ``cout << *i << ``" "``;``}` `// Driver code``int` `main()``{``    ``int` `arr[] = {2, 3, 4, 5, 6};``    ``int` `n = ``sizeof``(arr)/``sizeof``(arr);``    ``printDistSum(arr, n);``    ``return` `0;``}`

## Java

 `// Java program to print distinct``// subset sums of a given array.``import` `java.io.*;``import` `java.util.*;` `class` `GFG``{``    ``// sum denotes the current sum``    ``// of the subset currindex denotes``    ``// the index we have reached in``    ``// the given array``    ``static` `void` `distSumRec(``int` `arr[], ``int` `n, ``int` `sum,``                          ``int` `currindex, HashSet s)``    ``{``        ``if` `(currindex > n)``            ``return``;` `        ``if` `(currindex == n) {``            ``s.add(sum);``            ``return``;``        ``}` `        ``distSumRec(arr, n, sum + arr[currindex],``                    ``currindex + ``1``, s);``        ``distSumRec(arr, n, sum, currindex + ``1``, s);``    ``}` `    ``// This function mainly calls``    ``// recursive function distSumRec()``    ``// to generate distinct sum subsets.``    ``// And finally prints the generated subsets.``    ``static` `void` `printDistSum(``int` `arr[], ``int` `n)``    ``{``        ``HashSet s = ``new` `HashSet<>();``        ``distSumRec(arr, n, ``0``, ``0``, s);` `        ``// Print the result``        ``for` `(``int` `i : s)``            ``System.out.print(i + ``" "``);``    ``}``    ` `    ``//Driver code``    ``public` `static` `void` `main(String[] args)``    ``{``        ``int` `arr[] = { ``2``, ``3``, ``4``, ``5``, ``6` `};``        ``int` `n = arr.length;``        ``printDistSum(arr, n);``    ``}``}` `// This code is contributed by Gitanjali.`

## Python3

 `# Python 3 program to print distinct subset sums of``# a given array.` `# sum denotes the current sum of the subset``# currindex denotes the index we have reached in``# the given array``def` `distSumRec(arr, n, ``sum``, currindex, s):``    ``if` `(currindex > n):``        ``return` `    ``if` `(currindex ``=``=` `n):``        ``s.add(``sum``)``        ``return` `    ``distSumRec(arr, n, ``sum` `+` `arr[currindex], currindex``+``1``, s)``    ``distSumRec(arr, n, ``sum``, currindex``+``1``, s)` `# This function mainly calls recursive function``# distSumRec() to generate distinct sum subsets.``# And finally prints the generated subsets.``def` `printDistSum(arr,n):``    ``s ``=` `set``()``    ``distSumRec(arr, n, ``0``, ``0``, s)` `    ``# Print the result``    ``for` `i ``in` `s:``        ``print``(i,end ``=` `" "``)` `# Driver code``if` `__name__ ``=``=` `'__main__'``:``    ``arr ``=` `[``2``, ``3``, ``4``, ``5``, ``6``]``    ``n ``=` `len``(arr)``    ``printDistSum(arr, n)` `# This code is contributed by``# Surendra_Gangwar`

## C#

 `// C# program to print distinct``// subset sums of a given array.``using` `System;``using` `System.Collections.Generic;` `class` `GFG``{``    ``// sum denotes the current sum``    ``// of the subset currindex denotes``    ``// the index we have reached in``    ``// the given array``    ``static` `void` `distSumRec(``int` `[]arr, ``int` `n, ``int` `sum,``                        ``int` `currindex, HashSet<``int``> s)``    ``{``        ``if` `(currindex > n)``            ``return``;` `        ``if` `(currindex == n)``        ``{``            ``s.Add(sum);``            ``return``;``        ``}` `        ``distSumRec(arr, n, sum + arr[currindex],``                    ``currindex + 1, s);``        ``distSumRec(arr, n, sum, currindex + 1, s);``    ``}` `    ``// This function mainly calls``    ``// recursive function distSumRec()``    ``// to generate distinct sum subsets.``    ``// And finally prints the generated subsets.``    ``static` `void` `printDistSum(``int` `[]arr, ``int` `n)``    ``{``        ``HashSet<``int``> s = ``new` `HashSet<``int``>();``        ``distSumRec(arr, n, 0, 0, s);` `        ``// Print the result``        ``foreach` `(``int` `i ``in` `s)``            ``Console.Write(i + ``" "``);``    ``}``    ` `    ``// Driver code``    ``public` `static` `void` `Main()``    ``{``        ``int` `[]arr = { 2, 3, 4, 5, 6 };``        ``int` `n = arr.Length;``        ``printDistSum(arr, n);``    ``}``}` `/* This code contributed by PrinciRaj1992 */`

## Javascript

 ``

Output:

`0 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 20`

Time Complexity: O(2n).
Auxiliary Space: O(N), due to the use of an unordered_set to store the subset sums.

Dynamic Programming Approach
The time complexity of the above problem can be improved using Dynamic Programming, especially when the sum of given elements is small. We can make a dp table with rows containing the size of the array and the size of the column will be the sum of all the elements in the array.

## C++

 `// C++ program to print distinct subset sums of``// a given array.``#include``using` `namespace` `std;` `// Uses Dynamic Programming to find distinct``// subset sums``void` `printDistSum(``int` `arr[], ``int` `n)``{``    ``int` `sum = 0;``    ``for` `(``int` `i=0; i

## Java

 `// Java program to print distinct``// subset sums of a given array.``import` `java.io.*;``import` `java.util.*;` `class` `GFG {` `    ``// Uses Dynamic Programming to``    ``// find distinct subset sums``    ``static` `void` `printDistSum(``int` `arr[], ``int` `n)``    ``{``        ``int` `sum = ``0``;``        ``for` `(``int` `i = ``0``; i < n; i++)``            ``sum += arr[i];` `        ``// dp[i][j] would be true if arr[0..i-1]``        ``// has a subset with sum equal to j.``        ``boolean``[][] dp = ``new` `boolean``[n + ``1``][sum + ``1``];` `        ``// There is always a subset with 0 sum``        ``for` `(``int` `i = ``0``; i <= n; i++)``            ``dp[i][``0``] = ``true``;` `        ``// Fill dp[][] in bottom up manner``        ``for` `(``int` `i = ``1``; i <= n; i++)``        ``{``            ``dp[i][arr[i - ``1``]] = ``true``;``            ``for` `(``int` `j = ``1``; j <= sum; j++)``            ``{``                ``// Sums that were achievable``                ``// without current array element``                ``if` `(dp[i - ``1``][j] == ``true``)``                ``{``                    ``dp[i][j] = ``true``;``                    ``dp[i][j + arr[i - ``1``]] = ``true``;``                ``}``            ``}``        ``}` `        ``// Print last row elements``        ``for` `(``int` `j = ``0``; j <= sum; j++)``            ``if` `(dp[n][j] == ``true``)``                ``System.out.print(j + ``" "``);``    ``}` `        ``// Driver code``    ``public` `static` `void` `main(String[] args)``    ``{``        ``int` `arr[] = { ``2``, ``3``, ``4``, ``5``, ``6` `};``        ``int` `n = arr.length;``        ``printDistSum(arr, n);``    ``}``}` `// This code is contributed by Gitanjali.`

## Python3

 `# Python3 program to print distinct subset``# Sums of a given array.` `# Uses Dynamic Programming to find``# distinct subset Sums``def` `printDistSum(arr, n):` `    ``Sum` `=` `sum``(arr)``    ` `    ``# dp[i][j] would be true if arr[0..i-1]``    ``# has a subset with Sum equal to j.``    ``dp ``=` `[[``False` `for` `i ``in` `range``(``Sum` `+` `1``)]``                 ``for` `i ``in` `range``(n ``+` `1``)]``                 ` `    ``# There is always a subset with 0 Sum``    ``for` `i ``in` `range``(n ``+` `1``):``        ``dp[i][``0``] ``=` `True` `    ``# Fill dp[][] in bottom up manner``    ``for` `i ``in` `range``(``1``, n ``+` `1``):` `        ``dp[i][arr[i ``-` `1``]] ``=` `True` `        ``for` `j ``in` `range``(``1``, ``Sum` `+` `1``):``            ` `            ``# Sums that were achievable``            ``# without current array element``            ``if` `(dp[i ``-` `1``][j] ``=``=` `True``):``                ``dp[i][j] ``=` `True``                ``dp[i][j ``+` `arr[i ``-` `1``]] ``=` `True``            ` `    ``# Print last row elements``    ``for` `j ``in` `range``(``Sum` `+` `1``):``        ``if` `(dp[n][j] ``=``=` `True``):``            ``print``(j, end ``=` `" "``)` `# Driver code``arr ``=` `[``2``, ``3``, ``4``, ``5``, ``6``]``n ``=` `len``(arr)``printDistSum(arr, n)` `# This code is contributed``# by mohit kumar`

## C#

 `// C# program to print distinct``// subset sums of a given array.``using` `System;`` ` `class` `GFG {`` ` `    ``// Uses Dynamic Programming to``    ``// find distinct subset sums``    ``static` `void` `printDistSum(``int` `[]arr, ``int` `n)``    ``{``        ``int` `sum = 0;``        ``for` `(``int` `i = 0; i < n; i++)``            ``sum += arr[i];`` ` `        ``// dp[i][j] would be true if arr[0..i-1]``        ``// has a subset with sum equal to j.``        ``bool` `[,]dp = ``new` `bool``[n + 1,sum + 1];`` ` `        ``// There is always a subset with 0 sum``        ``for` `(``int` `i = 0; i <= n; i++)``            ``dp[i,0] = ``true``;`` ` `        ``// Fill dp[][] in bottom up manner``        ``for` `(``int` `i = 1; i <= n; i++)``        ``{``            ``dp[i,arr[i - 1]] = ``true``;``            ``for` `(``int` `j = 1; j <= sum; j++)``            ``{``                ``// Sums that were achievable``                ``// without current array element``                ``if` `(dp[i - 1,j] == ``true``)``                ``{``                    ``dp[i,j] = ``true``;``                    ``dp[i,j + arr[i - 1]] = ``true``;``                ``}``            ``}``        ``}`` ` `        ``// Print last row elements``        ``for` `(``int` `j = 0; j <= sum; j++)``            ``if` `(dp[n,j] == ``true``)``                ``Console.Write(j + ``" "``);``    ``}`` ` `    ``// Driver code``    ``public` `static` `void` `Main()``    ``{``        ``int` `[]arr = { 2, 3, 4, 5, 6 };``        ``int` `n = arr.Length;``        ``printDistSum(arr, n);``    ``}``}`` ` `// This code is contributed by nitin mittal.`

## Javascript

 ``

Output:

`0 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 20`

Time complexity of the above approach is O(n*sum) where n is the size of the array and sum is the sum of all the integers in the array.

Space Complexity: O(N * SUM). We are using a two-dimensional array of size N*SUM to store the solution to subproblems.

Optimized Bit-set Approach

`dp = dp | dp << a[i]`

Above Code snippet does the same as naive solution, where dp is a bit mask (we’ll use bit-set). Lets see how:

1. dp → all the sums which were produced before element a[i]
2. dp << a[i] → shifting all the sums by a[i], i.e. adding a[i] to all the sums.
1. For example, Suppose initially the bit-mask was 000010100 meaning we could generate only 2 and 4 (count from right).
2. Now if we get a element 3, we could make 5 and 7 as well by adding to 2 and 4 respectively.
3. This can be denoted by 010100000 which is equivalent to (000010100) << 3
3. dp | (dp << a[i])000010100 | 010100000 = 010110100 This is union of above two sums representing which sums are possible, namely 2, 4, 5 and 7. bitset optimized knapsack

## C++

 `// C++ Program to Demonstrate Bitset Optimised Knapsack``// Solution` `#include ``using` `namespace` `std;` `// Driver Code``int` `main()``{``    ``// Input Vector``    ``vector<``int``> a = { 2, 3, 4, 5, 6 };` `    ``// we have to make a constant size for bit-set``    ``// and to be safe keep it significantly high``    ``int` `n = a.size();``    ``const` `int` `mx = 40;` `    ``// bitset of size mx, dp[i] is 1 if sum i is possible``    ``// and 0 otherwise``    ``bitset dp;``    ``// sum 0 is always possible``    ``dp = 1;` `    ``// dp transitions as explained in article``    ``for` `(``int` `i = 0; i < n; ++i) {``        ``dp |= dp << a[i];``    ``}` `    ``// print all the  1s in bit-set, this will be the``    ``// all the unique sums possible``    ``for` `(``int` `i = 0; i <= mx; i++) {``        ``if` `(dp[i] == 1)``            ``cout << i << ``" "``;``    ``}``}` `// code is contributed by sarvjot singh`

## Javascript

 `// Javascript Program to Demonstrate Bit Optimised Knapsack``      ``// Solution` `      ``// Driver Code` `      ``// Input Array``      ``var` `a = [2, 3, 4, 5, 6];``      ``var` `n = a.length;` `      ``// Used a variable "dp" and intialized that with "1"``      ``// because sum 0 is always possible``      ``// Since binary of "1" is also "1" which means getting``      ``// "1" at 0th index and it means sum=0``      ``var` `dp = 1;` `      ``// dp transitions as explained in article``      ``for` `(``var` `i = 0; i < n; ++i) {``        ``dp |= dp << a[i];``      ``}` `      ``//Getting that dp as binary bits of string``      ``var` `ans = dp.toString(2);` `      ``// print all the  1s in that binary string, this will be the``      ``// all the unique sums possible``      ``for` `(``var` `j = 0; j <= ans.length; j++) {``        ``if` `(ans[j] == ``"1"``) {``          ``console.log(j + ``" "``);``        ``}``      ``}`

## Java

 `import` `java.util.*;` `public` `class` `BitsetKnapsack {`` ` `    ``public` `static` `void` `main(String[] args) {``        ``// Input Vector``        ``Integer[] a = {``2``, ``3``, ``4``, ``5``, ``6``};``        ` `        ``// we have to make a constant size for bit-set``        ``// and to be safe keep it significantly high``        ``int` `n = a.length;``        ``final` `int` `mx = ``40``;``        ` `        ``// bitset of size mx, dp[i] is 1 if sum i is possible``        ``// and 0 otherwise``        ``BitSet dp = ``new` `BitSet(mx);``        ``// sum 0 is always possible``        ``dp.set(``0``);``        ` `        ``// dp transitions as explained in article``        ``for` `(``int` `i = ``0``; i < n; ++i) {``            ``dp.or(dp.get(``0``, mx - a[i]));``            ``dp.set(a[i]);``        ``}``        ` `        ``// print all the  1s in bit-set, this will be the``        ``// all the unique sums possible``        ``for` `(``int` `i = ``0``; i <= mx; i++) {``            ``if` `(dp.get(i))``                ``System.out.print(i + ``" "``);``        ``}``    ``}``}`

## Python3

 `# Input Vector``a ``=` `[``2``, ``3``, ``4``, ``5``, ``6``]` `# We have to make a constant size for bit-set``# and to be safe keep it significantly high``n ``=` `len``(a)``mx ``=` `40` `# bitset of size mx, dp[i] is 1 if sum i is possible``# and 0 otherwise``dp ``=` `[``0``] ``*` `mx``# Sum 0 is always possible``dp[``0``] ``=` `1` `# dp transitions as explained in article``for` `i ``in` `range``(n):``    ``for` `j ``in` `range``(mx ``-` `a[i]):``        ``dp[j ``+` `a[i]] |``=` `dp[j]``    ``dp[a[i]] ``=` `1` `# Print all the  1s in bit-set, this will be the``# all the unique sums possible``for` `i ``in` `range``(mx):``    ``if` `dp[i] ``=``=` `1``:``        ``print``(i, end``=``' '``)`

Output

`0 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 20 `

Time Complexity also seems to be O(N * S). Because if we would have used a array instead of bitset the shifting would have taken linear time O(S). However the shift (and almost all) operation on bitset takes O(S / W) time. Where W is the word size of the system, Usually its 32 bit or 64 bit. Thus the final time complexity becomes O(N * S / W)

Space Complexity: The space complexity of this approach is O(m) where m is the maximum value of the input array.

Some Important Points:

1. The size of bitset must be a constant, this sometimes is a drawback as we might waste some space.
2. Bitset can be thought of a array where every element takes care of W elements. For example 010110100 is equivalent to {2, 6, 4} in a hypothetical system with word size W = 3.
3. Bitset optimized knapsack solution reduced the time complexity by a factor of W which sometimes is just enough to get AC.

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