Count subsequences for every array element in which they are the maximum
Last Updated :
03 Aug, 2022
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[0] ( = 2) is maximum are {2}, {2, 1}.
Subsequences in which arr[1] ( = 3) is maximum are {3}, {1, 3, 2}, {2, 3}, {1, 3}.
Subsequence in which arr[2] ( = 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:
- 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]].
- Initialize an integer, subseq with 1 to store the number of possible subsequences.
- Iterate N times with pointer over the range [0, N-1] using a variable, i.
- 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]].
- Store the answer for B[indices[i]] as B[indices[i]] = subseq.
- Update subseq by multiplying it by 2.
- 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 <bits/stdc++.h>
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 remaining 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 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[0]);
// 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 remaining 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 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 remaining 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 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 remaining 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 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
<script>
// JavaScript program for the above approach
// Function to merge the subarrays
// arr[l .. m] and arr[m + 1, .. r]
// based on indices[]
function merge(indices, a, l, mid, r)
{
let temp_ind = [];
let j = mid + 1;
let 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 remaining 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 parts
function divide(indices, a, l, r)
{
if (l >= r)
return;
let 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
function noOfSubsequences(arr, N)
{
let indices = [];
let 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
let B = [];
// Initialize subseq
let 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++)
document.write(B[i] + " ");
}
// Driver code
// Given array
let arr = [ 2, 3, 1 ];
// Given length
let N = arr.length;
// Function call
noOfSubsequences(arr, N);
// This code is contributed by avijitmondal1998
</script>
Time Complexity: O(NlogN) where N is the length of the given array.
Auxiliary Space: O(N)
Similar Reads
Count subsequences which contains both the maximum and minimum array element Given an array arr[] consisting of N integers, the task is to find the number of subsequences which contain the maximum as well as the minimum element present in the given array. Example : Input: arr[] = {1, 2, 3, 4}Output: 4Explanation: There are 4 subsequence {1, 4}, {1, 2, 4}, {1, 3, 4}, {1, 2, 3
6 min read
Count number of Subsequences in Array in which X and Y are min and max elements Given an array arr[] consisting of N unique elements, the task is to return the count of the subsequences in an array in which the minimum element is X and the maximum element is Y. Examples: Input: arr[] = {2, 4, 6, 7, 5}, X = 2, Y = 5Output: 2Explanation: Subsequences in which the minimum element
11 min read
Maximize count of Decreasing Subsequences from the given Array Given an array arr[], the task is to rearrange the array to generate maximum decreasing subsequences and print the count of the maximum number of subsequences possible such that each array element can be part of a single subsequence and the length of the subsequences needs to be maximized. Example:
5 min read
Count of subsequences in an array with sum less than or equal to X Given an integer array arr[] of size N and an integer X, the task is to count the number of subsequences in that array such that its sum is less than or equal to X. Note: 1 <= N <= 1000 and 1 <= X <= 1000, where N is the size of the array. Examples: Input : arr[] = {84, 87, 73}, X = 100
13 min read
Increase the count of given subsequences by optimizing the Array Given an array X[] of length N. Which contains the alternate frequency of 0s and 1s in Binary String starting from 0. Then the task is to maximize the count of the "01" subsequence where you can choose two different elements of X[], let's say Xi and Xj such that abs (i - j) = 2, and then swap Xi and
11 min read