Related Articles

# Median of all non-empty subset sums

• Last Updated : 02 Jun, 2021

Given an array, arr[] of size N, the task is to find the median of sums of all possible subsets of the given array.

Examples:

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.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

Input: arr = {2, 3, 3}
Output: 5
Explanation:
Non-Empty Subsets of the given array are: { {2}, {3}, {3}, {2, 3}, {2, 3}, {3, 3}, {2, 3, 3} }.
Possible sum of each subset are:
{ {2}, {3}, {3}, {5}, {5}, {6}, {8} }
Therefore, the median of all possible sum of each subset is 5.

Input: arr = {1, 2, 1}
Output: 2

Naive Approach: The simplest approach to solve this problem is to generate all possible subsets of the given array and find the sum of elements of each subset. Finally, print the median of all possible subset-sum.

Time Complexity: O(N * 2N)
Auxiliary Space: O(N * 2N)

Efficient Approach: To optimize the above approach the idea is to use Dynamic programming. Following are the relation of Dynamic programming states and the base cases:

Relation between DP states:
if j ≥ arr[i] then dp[i][j] = dp[i – 1][j] + dp[i – 1][j – arr[i]]
Otherwise, dp[i][j] = dp[i – 1][j]
where dp[i][j] denotes total number of ways to obtain the sum j either by selecting the ith element or not selecting the ith element.

Base case: dp[i] = 1

Follow the steps below to solve the problem:

• Initialize a 2D array, say DP[][] to store the above mentioned DP states.
• Fill all the dp[][] state in a bottom-up manner using the above-mentioned relation between the DP states.
• Initialize an array, say sumSub[] to store all possible sum of each subset.
• Traverse the dp[][] array and store sums of all possible subsets in the array sumSub[].
• Sort the sumSub[] array.
• Finally, print the middle element of sumSub[] array.

## C++

 `// C++ program to implement``// the above approach``  ` `#include  ``using` `namespace` `std; ``  ` `  ` `// Function to calculate the median of all ``// possible subsets by given operations``int` `findMedianOfsubSum(``int` `arr[], ``int` `N)``{   ``      ` `    ``// Stores sum of elements``    ``// of arr[]``    ``int` `sum=0;``      ` `      ` `    ``// Traverse the array arr[]``    ``for``(``int` `i=0; i < N; i++) {``          ` `          ` `       ``// Update sum``       ``sum += arr[i];``    ``}``      ` `      ` `    ``// Sort the array``    ``sort(arr, arr + N);``      ` `      ` `    ``// DP[i][j]: Stores total number of ways``    ``// to form the sum j by either selecting``    ``// ith element or not selecting ith item.``    ``int` `dp[N][sum+1];``      ` `      ` `    ``// Initialize all ``    ``// the DP states``    ``memset``(dp, 0, ``sizeof``(dp));``      ` `      ` `    ``// Base case``    ``for``(``int` `i=0; i < N; i++) {``          ` `          ` `       ``// Fill dp[i]``       ``dp[i] = 1;``    ``}``      ` `      ` `    ``// Base case``    ``dp[arr] = 1;``      ` `      ` `    ``// Fill all the DP states based ``    ``// on the mentioned DP relation``    ``for``(``int` `i = 1; i < N; i++) {``          ` `        ``for``(``int` `j = 1; j <= sum; j++) {``              ` `              ` `            ``// If j is greater than``            ``// or equal to arr[i]``            ``if``(j >= arr[i]) {``                  ` `                  ` `                ``// Update dp[i][j]    ``                ``dp[i][j] = dp[i-1][j] + ``                      ``dp[i-1][j-arr[i]];``            ``}``            ``else` `{``                  ` `                  ` `                ``// Update dp[i][j]``                ``dp[i][j] = dp[i-1][j];``            ``}``        ``}``    ``}``      ` `      ` `    ``// Stores all possible``    ``// subset sum``    ``vector<``int``> sumSub;``      ` `      ` `    ``// Traverse all possible subset sum``    ``for``(``int` `j=1; j <= sum; j++) {``          ` `          ` `       ``// Stores count of subsets ``       ``// whose sum is j``        ``int` `M = dp[N - 1][j];``          ` `          ` `       ``// Itearate over the range [1, M]``        ``for``(``int` `i = 1; i <= M; i++) {``              ` `              ` `            ``// Insert j into sumSub``            ``sumSub.push_back(j);``        ``}``    ``}``      ` `      ` `    ``// Stores middle element of sumSub ``    ``int` `mid = sumSub[sumSub.size() / 2];``      ` `    ``return` `mid; ``}``  ` `  ` `// Driver Code``int` `main()``{``    ``int` `arr[] = { 2, 3, 3 };``    ``int` `N = ``sizeof``(arr) / ``sizeof``(arr);``    ``cout << findMedianOfsubSum(arr, N);``    ``return` `0;``}`

## Java

 `// Java program to implement``// the above approach``import` `java.util.*;` `class` `GFG{``    ` `// Function to calculate the median of all ``// possible subsets by given operations``static` `int` `findMedianOfsubSum(``int` `arr[], ``int` `N)``{``    ` `    ``// Stores sum of elements``    ``// of arr[]``    ``int` `sum = ``0``;``      ` `    ``// Traverse the array arr[]``    ``for``(``int` `i = ``0``; i < N; i++)``    ``{``        ` `        ``// Update sum``        ``sum += arr[i];``    ``}``    ` `    ``// Sort the array``    ``Arrays.sort(arr);``    ` `    ``// DP[i][j]: Stores total number of ways``    ``// to form the sum j by either selecting``    ``// ith element or not selecting ith item.``    ``int` `[][]dp = ``new` `int``[N][sum + ``1``];``    ` `    ``// Initialize all ``    ``// the DP states``    ``for``(``int` `i = ``0``; i < N; i++)``    ``{``        ``for``(``int` `j = ``0``; j < sum + ``1``; j++)``            ``dp[i][j] = ``0``;``    ``}``    ` `    ``// Base case``    ``for``(``int` `i = ``0``; i < N; i++)``    ``{``        ` `        ``// Fill dp[i]``        ``dp[i][``0``] = ``1``;``    ``}``    ` `    ``// Base case``    ``dp[``0``][arr[``0``]] = ``1``;``      ` `    ``// Fill all the DP states based ``    ``// on the mentioned DP relation``    ``for``(``int` `i = ``1``; i < N; i++)``    ``{``        ``for``(``int` `j = ``1``; j <= sum; j++)``        ``{``            ` `            ``// If j is greater than``            ``// or equal to arr[i]``            ``if` `(j >= arr[i])``            ``{``                ` `                ``// Update dp[i][j]    ``                ``dp[i][j] = dp[i - ``1``][j] + ``                           ``dp[i - ``1``][j - arr[i]];``            ``}``            ``else``            ``{``                ` `                ``// Update dp[i][j]``                ``dp[i][j] = dp[i - ``1``][j];``            ``}``        ``}``    ``}``    ` `    ``// Stores all possible``    ``// subset sum``    ``Vector sumSub = ``new` `Vector();``    ` `    ``// Traverse all possible subset sum``    ``for``(``int` `j = ``1``; j <= sum; j++)``    ``{``        ` `        ``// Stores count of subsets ``        ``// whose sum is j``        ``int` `M = dp[N - ``1``][j];``        ` `        ``// Itearate over the range [1, M]``        ``for``(``int` `i = ``1``; i <= M; i++)``        ``{``            ` `            ``// Insert j into sumSub``            ``sumSub.add(j);``        ``}``    ``}``    ` `    ``// Stores middle element of sumSub ``    ``int` `mid = sumSub.get(sumSub.size() / ``2``);``      ` `    ``return` `mid; ``}``  ` `// Driver Code``public` `static` `void` `main(String args[])``{``    ``int` `arr[] = { ``2``, ``3``, ``3` `};``    ``int` `N = arr.length;``    ` `    ``System.out.print(findMedianOfsubSum(arr, N));``}``}`` ` `// This code is contributed by ipg2016107`

## Python3

 `# Python3 program to implement``# the above approach ``  ` `# Function to calculate the``# median of all possible subsets``# by given operations``def` `findMedianOfsubSum(arr, N):``  ` `    ``# Stores sum of elements``    ``# of arr[]``    ``sum` `=` `0`     `      ` `    ``# Traverse the array arr[]``    ``for` `i ``in` `range``(N):``      ` `        ``# Update sum``        ``sum` `+``=` `arr[i]     ``      ` `    ``# Sort the array``    ``arr.sort(reverse ``=` `False``)      ``      ` `    ``# DP[i][j]: Stores total number``    ``# of ways to form the sum j by``    ``# either selecting ith element``    ``# or not selecting ith item.``    ``dp ``=` `[[``0` `for` `i ``in` `range``(``sum` `+` `1``)]``             ``for` `j ``in` `range``(N)]     ``      ` `    ``# Base case``    ``for` `i ``in` `range``(N):``      ` `        ``# Fill dp[i]``        ``dp[i][``0``] ``=` `1`     `      ` `    ``# Base case``    ``dp[``0``][arr[``0``]] ``=` `1`     `      ` `    ``# Fill all the DP states based ``    ``# on the mentioned DP relation``    ``for` `i ``in` `range``(``1``, N, ``1``):``        ``for` `j ``in` `range``(``1``, ``sum` `+` `1``, ``1``):``          ` `            ``# If j is greater than``            ``# or equal to arr[i]``            ``if``(j >``=` `arr[i]):``              ` `                ``# Update dp[i][j]    ``                ``dp[i][j] ``=` `(dp[i ``-` `1``][j] ``+``                            ``dp[i ``-` `1``][j ``-` `arr[i]])``            ``else``:``              ` `                ``# Update dp[i][j]``                ``dp[i][j] ``=` `dp[i ``-` `1``][j]``            ` `    ``# Stores all possible``    ``# subset sum``    ``sumSub ``=` `[]     ``      ` `    ``# Traverse all possible``    ``# subset sum``    ``for` `j ``in` `range``(``1``, ``sum` `+` `1``, ``1``):``      ` `        ``# Stores count of subsets``        ``# whose sum is j``        ``M ``=` `dp[N ``-` `1``][j]         ``           ` `        ``# Itearate over the``        ``# range [1, M]``        ``for` `i ``in` `range``(``1``, M ``+` `1``, ``1``):``          ` `            ``# Insert j into sumSub``            ``sumSub.append(j)     ``      ` `    ``# Stores middle element``    ``# of sumSub ``    ``mid ``=` `sumSub[``len``(sumSub) ``/``/` `2``]``      ` `    ``return` `mid ``  ` `# Driver Code``if` `__name__ ``=``=` `'__main__'``:``  ` `    ``arr ``=` `[``2``, ``3``, ``3``]``    ``N ``=` `len``(arr)``    ``print``(findMedianOfsubSum(arr, N))``    ` `# Thsi code is contributed by bgangwar59`

## C#

 `// C# program to implement``// the above approach ``using` `System;``using` `System.Collections.Generic;`` ` `class` `GFG{`` ` `// Function to calculate the median of all ``// possible subsets by given operations``static` `int` `findMedianOfsubSum(``int``[] arr, ``int` `N)``{``    ` `    ``// Stores sum of elements``    ``// of arr[]``    ``int` `sum = 0;``       ` `    ``// Traverse the array arr[]``    ``for``(``int` `i = 0; i < N; i++)``    ``{``        ` `        ``// Update sum``        ``sum += arr[i];``    ``}``     ` `    ``// Sort the array``    ``Array.Sort(arr);``     ` `    ``// DP[i][j]: Stores total number of ways``    ``// to form the sum j by either selecting``    ``// ith element or not selecting ith item.``    ``int` `[,]dp = ``new` `int``[N, sum + 1];``     ` `    ``// Initialize all ``    ``// the DP states``    ``for``(``int` `i = 0; i < N; i++)``    ``{``        ``for``(``int` `j = 0; j < sum + 1; j++)``            ``dp[i, j] = 0;``    ``}``     ` `    ``// Base case``    ``for``(``int` `i = 0; i < N; i++)``    ``{``        ` `        ``// Fill dp[i]``        ``dp[i, 0] = 1;``    ``}``     ` `    ``// Base case``    ``dp[0, arr] = 1;``       ` `    ``// Fill all the DP states based ``    ``// on the mentioned DP relation``    ``for``(``int` `i = 1; i < N; i++)``    ``{``        ``for``(``int` `j = 1; j <= sum; j++)``        ``{``            ` `            ``// If j is greater than``            ``// or equal to arr[i]``            ``if` `(j >= arr[i])``            ``{``                 ` `                ``// Update dp[i][j]    ``                ``dp[i, j] = dp[i - 1, j] + ``                           ``dp[i - 1, j - arr[i]];``            ``}``            ``else``            ``{``                ` `                ``// Update dp[i][j]``                ``dp[i, j] = dp[i - 1, j];``            ``}``        ``}``    ``}``     ` `    ``// Stores all possible``    ``// subset sum``    ``List<``int``> sumSub = ``new` `List<``int``>();``    ` `    ``// Traverse all possible subset sum``    ``for``(``int` `j = 1; j <= sum; j++)``    ``{``         ` `        ``// Stores count of subsets ``        ``// whose sum is j``        ``int` `M = dp[N - 1, j];``         ` `        ``// Itearate over the range [1, M]``        ``for``(``int` `i = 1; i <= M; i++)``        ``{``             ` `            ``// Insert j into sumSub``            ``sumSub.Add(j);``        ``}``    ``}``     ` `    ``// Stores middle element of sumSub ``    ``int` `mid = sumSub[sumSub.Count / 2];``       ` `    ``return` `mid; ``}` `// Driver code``public` `static` `void` `Main()``{``    ``int``[] arr = { 2, 3, 3 };``    ``int` `N = arr.Length;``     ` `    ``Console.Write(findMedianOfsubSum(arr, N));``}``}` `// This code is contributed by sanjoy_62`

## Javascript

 ``
Output
`5`

My Personal Notes arrow_drop_up