Related Articles

# Count subsequences for every array element in which they are the maximum

• Last Updated : 09 Jul, 2021

Given an array arr[] consisting of N unique elements, the task is to generate an array B[] of length N such that B[i] is the number of subsequences in which arr[i] is the maximum element.

Examples:

Input: arr[] = {2, 3, 1}
Output: {2, 4, 1}
Explanation: Subsequences in which arr ( = 2) is maximum are {2}, {2, 1}.
Subsequences in which arr ( = 3) is maximum are {3}, {1, 3, 2}, {2, 3}, {1, 3}.
Subsequence in which arr ( = 1) is maximum is {1}.

Input: arr[] = {23, 34, 12, 7, 15, 31}
Output: {8, 32, 2, 1, 4, 16}

Approach: The problem can be solved by observing that all the subsequences where an element, arr[i], will appear as the maximum will contain all the elements less than arr[i]. Therefore, the total number of distinct subsequences will be 2(Number of elements less than arr[i]). Follow the steps below to solve the problem:

1. Sort the array arr[] indices with respect to their corresponding values present in the given array and store that indices in array indices[], where arr[indices[i]] < arr[indices[i+1]].
2. Initialize an integer, subseq with 1 to store the number of possible subsequences.
3. Iterate N times with pointer over the range [0, N-1] using a variable, i.
1. B[indices[i]] is the number of subsequences in which arr[indices[i]] is maximum i.e., 2i, as there will be i elements less than arr[indices[i]].
2. Store the answer for B[indices[i]] as B[indices[i]] = subseq.
3. Update subseq by multiplying it by 2.
4. Print the elements of the array B[] as the answer.

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach` `#include ``using` `namespace` `std;` `// Function to merge the subarrays``// arr[l .. m] and arr[m + 1, .. r]``// based on indices[]``void` `merge(``int``* indices, ``int``* a, ``int` `l,``           ``int` `mid, ``int` `r)``{``    ``int` `temp_ind[r - l + 1], j = mid + 1;``    ``int` `i = 0, temp_l = l, k;``    ``while` `(l <= mid && j <= r) {` `        ``// If a[indices[l]] is less than``        ``// a[indices[j]], add indice[l] to temp``        ``if` `(a[indices[l]] < a[indices[j]])``            ``temp_ind[i++] = indices[l++];` `        ``// Else add indices[j]``        ``else``            ``temp_ind[i++] = indices[j++];``    ``}` `    ``// Add remaining elements``    ``while` `(l <= mid)``        ``temp_ind[i++] = indices[l++];` `    ``// Add remainging elements``    ``while` `(j <= r)``        ``temp_ind[i++] = indices[j++];``    ``for` `(k = 0; k < i; k++)``        ``indices[temp_l++] = temp_ind[k];``}` `// Recursive function to divide``// the array into to parts``void` `divide(``int``* indices, ``int``* a, ``int` `l, ``int` `r)``{``    ``if` `(l >= r)``        ``return``;``    ``int` `mid = l / 2 + r / 2;` `    ``// Recursive call for elements before mid``    ``divide(indices, a, l, mid);` `    ``// Recursive call for elements after mid``    ``divide(indices, a, mid + 1, r);` `    ``// Merge the two sorted arrays``    ``merge(indices, a, l, mid, r);``}` `// Function to find the number of``// subsequences for each element``void` `noOfSubsequences(``int` `arr[], ``int` `N)``{``    ``int` `indices[N], i;``    ``for` `(i = 0; i < N; i++)``        ``indices[i] = i;` `    ``// Sorting the indices according``    ``// to array arr[]``    ``divide(indices, arr, 0, N - 1);` `    ``// Array to store output numbers``    ``int` `B[N];` `    ``// Initialize subseq``    ``int` `subseq = 1;``    ``for` `(i = 0; i < N; i++) {` `        ``// B[i] is 2^i``        ``B[indices[i]] = subseq;` `        ``// Doubling the subsequences``        ``subseq *= 2;``    ``}``    ``// Print the final output, array B[]``    ``for` `(i = 0; i < N; i++)``        ``cout << B[i] << ``" "``;``}` `// Driver Code``int` `main()``{` `    ``// Given array``    ``int` `arr[] = { 2, 3, 1 };` `    ``// Given length``    ``int` `N = ``sizeof``(arr) / ``sizeof``(arr);` `    ``// Function call``    ``noOfSubsequences(arr, N);``    ``return` `0;``}`

## Java

 `// Java program for the above approach``import` `java.util.*;` `class` `GFG{` `// Function to merge the subarrays``// arr[l .. m] and arr[m + 1, .. r]``// based on indices[]``static` `void` `merge(``int``[] indices, ``int``[] a, ``int` `l,``                  ``int` `mid, ``int` `r)``{``    ``int` `[]temp_ind = ``new` `int``[r - l + ``1``];``    ``int` `j = mid + ``1``;``    ``int` `i = ``0``, temp_l = l, k;``    ` `    ``while` `(l <= mid && j <= r)``    ``{``        ` `        ``// If a[indices[l]] is less than``        ``// a[indices[j]], add indice[l] to temp``        ``if` `(a[indices[l]] < a[indices[j]])``            ``temp_ind[i++] = indices[l++];` `        ``// Else add indices[j]``        ``else``            ``temp_ind[i++] = indices[j++];``    ``}` `    ``// Add remaining elements``    ``while` `(l <= mid)``        ``temp_ind[i++] = indices[l++];` `    ``// Add remainging elements``    ``while` `(j <= r)``        ``temp_ind[i++] = indices[j++];``        ` `    ``for``(k = ``0``; k < i; k++)``        ``indices[temp_l++] = temp_ind[k];``}` `// Recursive function to divide``// the array into to parts``static` `void` `divide(``int``[] indices, ``int``[] a,``                   ``int` `l, ``int` `r)``{``    ``if` `(l >= r)``        ``return``;``        ` `    ``int` `mid = l / ``2` `+ r / ``2``;` `    ``// Recursive call for elements before mid``    ``divide(indices, a, l, mid);` `    ``// Recursive call for elements after mid``    ``divide(indices, a, mid + ``1``, r);` `    ``// Merge the two sorted arrays``    ``merge(indices, a, l, mid, r);``}` `// Function to find the number of``// subsequences for each element``static` `void` `noOfSubsequences(``int` `arr[], ``int` `N)``{``    ``int` `[]indices = ``new` `int``[N];``    ``int` `i;``    ` `    ``for``(i = ``0``; i < N; i++)``        ``indices[i] = i;` `    ``// Sorting the indices according``    ``// to array arr[]``    ``divide(indices, arr, ``0``, N - ``1``);` `    ``// Array to store output numbers``    ``int``[] B = ``new` `int``[N];` `    ``// Initialize subseq``    ``int` `subseq = ``1``;``    ` `    ``for``(i = ``0``; i < N; i++)``    ``{``        ` `        ``// B[i] is 2^i``        ``B[indices[i]] = subseq;` `        ``// Doubling the subsequences``        ``subseq *= ``2``;``    ``}``    ` `    ``// Print the final output, array B[]``    ``for``(i = ``0``; i < N; i++)``        ``System.out.print(B[i] + ``" "``);``}` `// Driver Code``public` `static` `void` `main(String[] args)``{``    ` `    ``// Given array``    ``int` `arr[] = { ``2``, ``3``, ``1` `};` `    ``// Given length``    ``int` `N = arr.length;` `    ``// Function call``    ``noOfSubsequences(arr, N);``}``}` `// This code is contributed by Princi Singh`

## Python3

 `# Python3 program for the above approach` `# Function to merge the subarrays``# arr[l .. m] and arr[m + 1, .. r]``# based on indices[]``def` `merge(indices, a, l, mid, r):` `    ``temp_ind ``=` `[``0``] ``*` `(r ``-` `l ``+` `1``)``    ``j ``=` `mid ``+` `1``    ``i ``=` `0``    ``temp_l ``=` `l``    ` `    ``while` `(l <``=` `mid ``and` `j <``=` `r):``        ` `        ``# If a[indices[l]] is less than``        ``# a[indices[j]], add indice[l] to temp``        ``if` `(a[indices[l]] < a[indices[j]]):``            ``temp_ind[i] ``=` `indices[l]``            ``i ``+``=` `1``            ``l ``+``=` `1` `        ``# Else add indices[j]``        ``else``:``            ``temp_ind[i] ``=` `indices[j]``            ``i ``+``=` `1``            ``j ``+``=` `1` `    ``# Add remaining elements``    ``while` `(l <``=` `mid):``        ``temp_ind[i] ``=` `indices[l]``        ``i ``+``=` `1``        ``l ``+``=` `1` `    ``# Add remainging elements``    ``while` `(j <``=` `r):``        ``temp_ind[i] ``=` `indices[j]``        ``i ``+``=` `1``        ``j ``+``=` `1``        ` `    ``for` `k ``in` `range``(i):``        ``indices[temp_l] ``=` `temp_ind[k]``        ``temp_l ``+``=` `1` `# Recursive function to divide``# the array into to parts``def` `divide(indices, a, l, r):` `    ``if` `(l >``=` `r):``        ``return``    ` `    ``mid ``=` `l ``/``/` `2` `+` `r ``/``/` `2` `    ``# Recursive call for elements``    ``# before mid``    ``divide(indices, a, l, mid)` `    ``# Recursive call for elements``    ``# after mid``    ``divide(indices, a, mid ``+` `1``, r)` `    ``# Merge the two sorted arrays``    ``merge(indices, a, l, mid, r)` `# Function to find the number of``# subsequences for each element``def` `noOfSubsequences(arr, N):` `    ``indices ``=` `N ``*` `[``0``]``    ``for` `i ``in` `range``(N):``        ``indices[i] ``=` `i` `    ``# Sorting the indices according``    ``# to array arr[]``    ``divide(indices, arr, ``0``, N ``-` `1``)` `    ``# Array to store output numbers``    ``B ``=` `[``0``] ``*` `N` `    ``# Initialize subseq``    ``subseq ``=` `1``    ``for` `i ``in` `range``(N):` `        ``# B[i] is 2^i``        ``B[indices[i]] ``=` `subseq` `        ``# Doubling the subsequences``        ``subseq ``*``=` `2` `    ``# Print the final output, array B[]``    ``for` `i ``in` `range``(N):``        ``print``(B[i], end ``=` `" "``)` `# Driver Code``if` `__name__ ``=``=` `"__main__"``:` `    ``# Given array``    ``arr ``=` `[ ``2``, ``3``, ``1` `]` `    ``# Given length``    ``N ``=` `len``(arr)` `    ``# Function call``    ``noOfSubsequences(arr, N)` `# This code is contributed by chitranayal`

## C#

 `// C# program for the above approach``using` `System;` `class` `GFG{` `// Function to merge the subarrays``// arr[l .. m] and arr[m + 1, .. r]``// based on indices[]``static` `void` `merge(``int``[] indices, ``int``[] a, ``int` `l,``                  ``int` `mid, ``int` `r)``{``    ``int` `[]temp_ind = ``new` `int``[r - l + 1];``    ``int` `j = mid + 1;``    ``int` `i = 0, temp_l = l, k;``    ` `    ``while` `(l <= mid && j <= r)``    ``{``        ` `        ``// If a[indices[l]] is less than``        ``// a[indices[j]], add indice[l] to temp``        ``if` `(a[indices[l]] < a[indices[j]])``            ``temp_ind[i++] = indices[l++];` `        ``// Else add indices[j]``        ``else``            ``temp_ind[i++] = indices[j++];``    ``}` `    ``// Add remaining elements``    ``while` `(l <= mid)``        ``temp_ind[i++] = indices[l++];` `    ``// Add remainging elements``    ``while` `(j <= r)``        ``temp_ind[i++] = indices[j++];``        ` `    ``for``(k = 0; k < i; k++)``        ``indices[temp_l++] = temp_ind[k];``}` `// Recursive function to divide``// the array into to parts``static` `void` `divide(``int``[] indices, ``int``[] a,``                   ``int` `l, ``int` `r)``{``    ``if` `(l >= r)``        ``return``;``        ` `    ``int` `mid = l / 2 + r / 2;` `    ``// Recursive call for elements before mid``    ``divide(indices, a, l, mid);` `    ``// Recursive call for elements after mid``    ``divide(indices, a, mid + 1, r);` `    ``// Merge the two sorted arrays``    ``merge(indices, a, l, mid, r);``}` `// Function to find the number of``// subsequences for each element``static` `void` `noOfSubsequences(``int` `[]arr, ``int` `N)``{``    ``int` `[]indices = ``new` `int``[N];``    ``int` `i;``    ` `    ``for``(i = 0; i < N; i++)``        ``indices[i] = i;` `    ``// Sorting the indices according``    ``// to array []arr``    ``divide(indices, arr, 0, N - 1);` `    ``// Array to store output numbers``    ``int``[] B = ``new` `int``[N];` `    ``// Initialize subseq``    ``int` `subseq = 1;``    ` `    ``for``(i = 0; i < N; i++)``    ``{``        ` `        ``// B[i] is 2^i``        ``B[indices[i]] = subseq;` `        ``// Doubling the subsequences``        ``subseq *= 2;``    ``}``    ` `    ``// Print the readonly output, array []B``    ``for``(i = 0; i < N; i++)``        ``Console.Write(B[i] + ``" "``);``}` `// Driver Code``public` `static` `void` `Main(String[] args)``{``    ` `    ``// Given array``    ``int` `[]arr = { 2, 3, 1 };` `    ``// Given length``    ``int` `N = arr.Length;` `    ``// Function call``    ``noOfSubsequences(arr, N);``}``}` `// This code is contributed by Amit Katiyar`

## Javascript

 ``
Output:
`2 4 1`

Time Complexity: O(NlogN) where N is the length of the given array.
Auxiliary Space: O(N)

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.

My Personal Notes arrow_drop_up