Count number of subsets whose median is also present in the same subset

Given an array arr[] of size N, the task is to count the number of ways we can select a subset from the given array elements such that the median of the selected subset is also present as an element in the subset. Since this number may be large, compute it modulo 1000000007.

Examples:

Input: arr[] = {2, 3, 2}
Output: 5
{2}, {3}, {2}, {2, 2} and {2, 3, 2} are all possible valid sub-sets.

Input: arr[] = {1, 4, 2, 2, 3, 5}
Output: 36

Approach:

  • Every subset of odd size has its median present in the subset, so, we can directly add 2N – 1 to the answer.
  • For even size subset, The subset will be selected, if and only if middle two elements are equal.
  • We need to count the number of even sized subsets with equal middle elements.

The Simple solution would be to iterate over every pair of equal elements (i, j) such that A[i] = A[j] and iterate over the size 2 * X of subset from X = 1 to N. The number of ways to make the subset of size X with two fixed middle elements is just the product of the number of ways we can select X – 1 elements from [1, i – 1] and X – 1 elements from [j + 1, N].

This solution requires to iterate over every pair (i, j) which takes O(N2) time and O(N) time per pair, leading to Overall time complexity O(N3)

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the approach
#include <algorithm>
#include <iostream>
using namespace std;
long long mod = 1000000007;
  
// Function to return the factorial of a number
int fact(int n)
{
    int res = 1;
    for (int i = 2; i <= n; i++)
        res = res * i;
    return res;
}
  
// Function to return the value of nCr
int nCr(int n, int r)
{
    return fact(n) / (fact(r) * fact(n - r));
}
  
// Function to return a raised to the power n
// with complexity O(log(n))
long long powmod(long long a, long long n)
{
    if (!n)
        return 1;
    long long pt = powmod(a, n / 2);
    pt = (pt * pt) % mod;
    if (n % 2)
        return (pt * a) % mod;
    else
        return pt;
}
  
// Function to return the number of sub-sets
// whose median is also present in the set
long long CountSubset(int* arr, int n)
{
  
    // Number of odd length sub-sets
    long long ans = powmod(2, n - 1);
  
    // Sort the array
    sort(arr, arr + n);
    for (int i = 0; i < n; ++i) {
        int j = i + 1;
  
        // Checking each element for leftmost middle
        // element while they are equal
        while (j < n && arr[j] == arr[i]) {
  
            // Calculate the number of elements in
            // right of rightmost middle element
            int r = n - 1 - j;
  
            // Calculate the number of elements in
            // left of leftmost middle element
            int l = i;
  
            // Add selected even length subsets
            // to the answer
            ans = (ans + nCr(l + r, l)) % mod;
            j++;
        }
    }
  
    return ans;
}
  
// Driver code
int main()
{
    int arr[] = { 2, 3, 2 };
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << CountSubset(arr, n) << endl;
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of the approach
import java.util.*;
  
class GFG {
  
    static long mod = 1000000007;
  
    // Function to return the factorial of a number
    static int fact(int n)
    {
        int res = 1;
        for (int i = 2; i <= n; i++)
            res = res * i;
        return res;
    }
  
    // Function to return the value of nCr
    static int nCr(int n, int r)
    {
        return fact(n) / (fact(r) * fact(n - r));
    }
  
    // Function to return a raised to the power n
    // with complexity O(log(n))
    static long powmod(long a, long n)
    {
        if (n == 0)
            return 1;
        long pt = powmod(a, n / 2);
        pt = (pt * pt) % mod;
        if (n % 2 == 1)
            return (pt * a) % mod;
        else
            return pt;
    }
  
    // Function to return the number of sub-sets
    // whose median is also present in the set
    static long CountSubset(int[] arr, int n)
    {
  
        // Number of odd length sub-sets
        long ans = powmod(2, n - 1);
  
        // Sort the array
        Arrays.sort(arr);
        for (int i = 0; i < n; ++i) {
            int j = i + 1;
  
            // Checking each element for leftmost middle
            // element while they are equal
            while (j < n && arr[j] == arr[i]) {
  
                // Calculate the number of elements in
                // right of rightmost middle element
                int r = n - 1 - j;
  
                // Calculate the number of elements in
                // left of leftmost middle element
                int l = i;
  
                // Add selected even length subsets
                // to the answer
                ans = (ans + nCr(l + r, l)) % mod;
                j++;
            }
        }
  
        return ans;
    }
  
    // Driver code
    public static void main(String[] args)
    {
        int arr[] = { 2, 3, 2 };
        int n = arr.length;
        System.out.println(CountSubset(arr, n));
    }
}
  
// This code has been contributed by 29AjayKumar

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python 3 implementation of the approach
mod = 1000000007
  
# Function to return 
# the factorial of a number
def fact(n):
    res = 1
    for i in range(2, n + 1):
        res = res * i
    return res
  
# Function to return the value of nCr
def nCr(n, r):
    return int(fact(n) / (fact(r) * 
                          fact(n - r)))
  
# Function to return 'a' raised to the power n
# with complexity O(log(n))
def powmod(a, n):
    if (n == 0):
        return 1
    pt = powmod(a, int(n / 2))
    pt = (pt * pt) % mod
    if (n % 2):
        return (pt * a) % mod
    else:
        return pt
  
# Function to return the number of sub-sets
# whose median is also present in the set
def CountSubset(arr, n):
      
    # Number of odd length sub-sets
    ans = powmod(2, n - 1)
  
    # Sort the array
    arr.sort(reverse = False)
    for i in range(n):
        j = i + 1
  
        # Checking each element for leftmost middle
        # element while they are equal
        while (j < n and arr[j] == arr[i]):
              
            # Calculate the number of elements in
            # right of rightmost middle element
            r = n - 1 - j
  
            # Calculate the number of elements in
            # left of leftmost middle element
            l = i
  
            # Add selected even length subsets
            # to the answer
            ans = (ans + nCr(l + r, l)) % mod
            j += 1
  
    return ans
  
# Driver code
if __name__ == '__main__':
    arr = [2, 3, 2]
    n = len(arr)
    print(CountSubset(arr, n))
  
# This code is contributed by
# Surendra_Gangwar

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# implementation of the approach
using System;
  
class GFG {
  
    static long mod = 1000000007;
  
    // Function to return the factorial of a number
    static int fact(int n)
    {
        int res = 1;
        for (int i = 2; i <= n; i++)
            res = res * i;
        return res;
    }
  
    // Function to return the value of nCr
    static int nCr(int n, int r)
    {
        return fact(n) / (fact(r) * fact(n - r));
    }
  
    // Function to return a raised to the power n
    // with complexity O(log(n))
    static long powmod(long a, long n)
    {
        if (n == 0)
            return 1;
        long pt = powmod(a, n / 2);
        pt = (pt * pt) % mod;
        if (n % 2 == 1)
            return (pt * a) % mod;
        else
            return pt;
    }
  
    // Function to return the number of sub-sets
    // whose median is also present in the set
    static long CountSubset(int[] arr, int n)
    {
  
        // Number of odd length sub-sets
        long ans = powmod(2, n - 1);
  
        // Sort the array
        Array.Sort(arr);
        for (int i = 0; i < n; ++i) {
            int j = i + 1;
  
            // Checking each element for leftmost middle
            // element while they are equal
            while (j < n && arr[j] == arr[i]) {
  
                // Calculate the number of elements in
                // right of rightmost middle element
                int r = n - 1 - j;
  
                // Calculate the number of elements in
                // left of leftmost middle element
                int l = i;
  
                // Add selected even length subsets
                // to the answer
                ans = (ans + nCr(l + r, l)) % mod;
                j++;
            }
        }
  
        return ans;
    }
  
    // Driver code
    public static void Main(String[] args)
    {
        int[] arr = { 2, 3, 2 };
        int n = arr.Length;
        Console.WriteLine(CountSubset(arr, n));
    }
}
  
// This code has been contributed by 29AjayKumar

chevron_right


PHP

filter_none

edit
close

play_arrow

link
brightness_4
code

<?php
// PHP implementation of the approach
$mod = 1000000007;
  
// Function to return the factorial of a number
function fact($n)
{
  
    $res = 1;
    for ($i = 2; $i <= $n; $i++)
        $res = $res * $i;
    return $res;
}
  
// Function to return the value of nCr
function nCr($n, $r)
{
    return fact($n) / (fact($r) * fact($n - $r));
}
  
// Function to return a raised to the power n
// with complexity O(log(n))
function powmod($a, $n)
{
    global $mod;
    if ($n == 0)
        return 1;
    $pt = powmod($a, $n / 2);
    $pt = ($pt * $pt) % $mod;
    if ($n % 2 == 1)
        return ($pt * $a) % $mod;
    else
        return $pt;
}
  
// Function to return the number of sub-sets
// whose median is also present in the set
function CountSubset( $arr, $n)
{
    global $mod;
      
    // Number of odd length sub-sets
    $ans = powmod(2, $n - 1);
  
    // Sort the array
    sort($arr, 0);
    for ($i = 0; $i < $n; ++$i
    {
        $j = $i + 1;
  
        // Checking each element for leftmost middle
        // element while they are equal
        while ($j < $n && $arr[$j] == $arr[$i]) 
        {
  
            // Calculate the number of elements in
            // right of rightmost middle element
            $r = $n - 1 - $j;
  
            // Calculate the number of elements in
            // left of leftmost middle element
            $l = $i;
  
            // Add selected even length subsets
            // to the answer
            $ans = ($ans + nCr($l + $r, $l)) % $mod;
            $j++;
        }
    }
  
    return $ans;
}
  
// Driver code
{
    $arr = array(2, 3, 2 );
    $n = sizeof($arr);
    echo(CountSubset($arr, $n));
}
  
// This code has been contributed by Code_Mech.

chevron_right


Output:

5

Time Complexity: O(N3)

The time complexity of the above approach can be reduced to O(N2) if we store pascal triangle in 2-d array. So, now we don’t have to calculate factorial again and again. Read more about Pascal triangle here.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the approach
#include <algorithm>
#include <iostream>
using namespace std;
long long mod = 1000000007;
long long arr[1001][1001];
  
// Function to store pascal triangle in 2-d array
void Preprocess()
{
    arr[0][0] = 1;
    for (int i = 1; i <= 1000; ++i) {
        arr[i][0] = 1;
        for (int j = 1; j < i; ++j) {
            arr[i][j] = (arr[i - 1][j - 1] + arr[i - 1][j]) % mod;
        }
        arr[i][i] = 1;
    }
}
  
// Function to return a raised to the power n
// with complexity O(log(n))
long long powmod(long long a, long long n)
{
    if (!n)
        return 1;
    long long pt = powmod(a, n / 2);
    pt = (pt * pt) % mod;
    if (n % 2)
        return (pt * a) % mod;
    else
        return pt;
}
  
// Function to return the number of sub-sets
// whose median is also present in the set
long long CountSubset(int* val, int n)
{
  
    // Number of odd length sub-sets
    long long ans = powmod(2, n - 1);
  
    // Sort the array
    sort(val, val + n);
    for (int i = 0; i < n; ++i) {
        int j = i + 1;
  
        // Checking each element for leftmost middle
        // element while they are equal
        while (j < n && val[j] == val[i]) {
  
            // Calculate the number of elements in
            // right of rightmost middle element
            int r = n - 1 - j;
  
            // Calculate the number of elements in
            // left of leftmost middle element
            int l = i;
  
            // Add selected even length subsets
            // to the answer
            ans = (ans + arr[l + r][l]) % mod;
            j++;
        }
    }
  
    return ans;
}
  
// Driver code
int main()
{
    Preprocess();
    int val[] = { 2, 3, 2 };
    int n = sizeof(val) / sizeof(val[0]);
    cout << CountSubset(val, n) << endl;
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of the above appraoch
import java.util.Arrays;
  
class GFG 
{
  
    static long mod = 1000000007;
    static long[][] arr = new long[1001][1001];
  
    // Function to store pascal triangle in 2-d array 
    static void Preprocess() 
    {
        arr[0][0] = 1;
        for (int i = 1; i <= 1000; ++i)
        {
            arr[i][0] = 1;
            for (int j = 1; j < i; ++j) 
            {
                arr[i][j] = (arr[i - 1][j - 1] + arr[i - 1][j]) % mod;
            }
            arr[i][i] = 1;
        }
    }
  
    // Function to return a raised to the power n 
    // with complexity O(log(n)) 
    static long powmod(long a, long n) 
    {
        if (n == 0)
        {
            return 1;
        }
        long pt = powmod(a, n / 2);
        pt = (pt * pt) % mod;
        if (n % 2 == 1
        {
            return (pt * a) % mod;
        
        else
        {
            return pt;
        }
    }
  
    // Function to return the number of sub-sets 
    // whose median is also present in the set 
    static long CountSubset(int[] val, int n)
    {
  
        // Number of odd length sub-sets 
        long ans = powmod(2, n - 1);
  
        // Sort the array 
        Arrays.sort(val);
        for (int i = 0; i < n; ++i) 
        {
            int j = i + 1;
  
            // Checking each element for leftmost middle 
            // element while they are equal 
            while (j < n && val[j] == val[i])
            {
  
                // Calculate the number of elements in 
                // right of rightmost middle element 
                int r = n - 1 - j;
  
                // Calculate the number of elements in 
                // left of leftmost middle element 
                int l = i;
  
                // Add selected even length subsets 
                // to the answer 
                ans = (ans + arr[l + r][l]) % mod;
                j++;
            }
        }
  
        return ans;
    }
  
    // Driver code 
    public static void main(String[] args)
    {
        Preprocess();
        int val[] = {2, 3, 2};
        int n = val.length;
  
        System.out.println(CountSubset(val, n));
    }
}
  
// This code contributed by Rajput-Ji

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implementation of the approach 
mod = 1000000007 
arr = [[None for i in range(1001)] for j in range(1001)] 
  
# Function to store pascal triangle in 2-d array 
def Preprocess(): 
   
    arr[0][0] = 1 
    for i in range(1, 1001):  
        arr[i][0] = 1 
        for j in range(1, i):  
            arr[i][j] = (arr[i - 1][j - 1] + arr[i - 1][j]) % mod 
           
        arr[i][i] = 1 
       
# Function to return a raised to the power n 
# with complexity O(log(n)) 
def powmod(a, n): 
   
    if not n: 
        return 1 
    pt = powmod(a, n // 2
    pt = (pt * pt) % mod 
    if n % 2
        return (pt * a) % mod 
    else:
        return pt 
  
# Function to return the number of sub-sets 
# whose median is also present in the set 
def CountSubset(val, n): 
   
    # Number of odd length sub-sets 
    ans = powmod(2, n - 1
  
    # Sort the array 
    val.sort() 
    for i in range(0, n):  
        j = i + 1 
  
        # Checking each element for leftmost middle 
        # element while they are equal 
        while j < n and val[j] == val[i]:  
  
            # Calculate the number of elements in 
            # right of rightmost middle element 
            r = n - 1 -
  
            # Calculate the number of elements in 
            # left of leftmost middle element 
            l =
  
            # Add selected even length 
            # subsets to the answer 
            ans = (ans + arr[l + r][l]) % mod 
            j += 1
  
    return ans 
   
# Driver code 
if __name__ == "__main__"
   
    Preprocess() 
    val = [2, 3, 2]
    n = len(val) 
    print(CountSubset(val, n))
  
# This code is contributed by Rituraj Jain

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# implementation of the above appraoch
using System;
      
class GFG 
{
  
    static long mod = 1000000007;
    static long [,]arr = new long[1001,1001];
  
    // Function to store pascal triangle in 2-d array 
    static void Preprocess() 
    {
        arr[0,0] = 1;
        for (int i = 1; i <= 1000; ++i)
        {
            arr[i,0] = 1;
            for (int j = 1; j < i; ++j) 
            {
                arr[i,j] = (arr[i - 1,j - 1] + arr[i - 1,j]) % mod;
            }
            arr[i,i] = 1;
        }
    }
  
    // Function to return a raised to the power n 
    // with complexity O(log(n)) 
    static long powmod(long a, long n) 
    {
        if (n == 0)
        {
            return 1;
        }
        long pt = powmod(a, n / 2);
        pt = (pt * pt) % mod;
        if (n % 2 == 1) 
        {
            return (pt * a) % mod;
        
        else
        {
            return pt;
        }
    }
  
    // Function to return the number of sub-sets 
    // whose median is also present in the set 
    static long CountSubset(int[] val, int n)
    {
  
        // Number of odd length sub-sets 
        long ans = powmod(2, n - 1);
  
        // Sort the array 
        Array.Sort(val);
        for (int i = 0; i < n; ++i) 
        {
            int j = i + 1;
  
            // Checking each element for leftmost middle 
            // element while they are equal 
            while (j < n && val[j] == val[i])
            {
  
                // Calculate the number of elements in 
                // right of rightmost middle element 
                int r = n - 1 - j;
  
                // Calculate the number of elements in 
                // left of leftmost middle element 
                int l = i;
  
                // Add selected even length subsets 
                // to the answer 
                ans = (ans + arr[l + r,l]) % mod;
                j++;
            }
        }
  
        return ans;
    }
  
    // Driver code 
    public static void Main(String[] args)
    {
        Preprocess();
        int []val = {2, 3, 2};
        int n = val.Length;
  
        Console.WriteLine(CountSubset(val, n));
    }
}
  
/* This code contributed by PrinciRaj1992 */

chevron_right


Output:

5

Time Complexity: O(N2)



My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

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

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.