Given an array arr[] of N elements and a positive integer K such that K ≤ N. The task is to find the number of subsequences of maximum length K i.e. subsequences of length 0, 1, 2, …, K – 1, K that have all distinct elements.
Examples:
Input: arr[] = {2, 2, 3, 3, 5}, K = 2
Output: 14
All the valid subsequences are {}, {2}, {2}, {3}, {3}, {5},
{2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 5}, {2, 5}, {3, 5} and {3, 5}.Input: arr[] = {1, 2, 3, 4, 4}, K = 4
Output: 24
Approach:
- Sort the array a[] if it is not already sorted and in a vector arr[] store the frequencies of each element of the original array. For example, if a[] = {2, 2, 3, 3, 5} then arr[] = {2, 2, 1} because 2 is present twice, 3 is present twice and 5 only once.
- Say m is the length of the vector arr[]. So m will be the number of distinct elements. There can be subsequences of maximum length m without repeatation. If m < k then there is no subsequence of length k. So, declare n = minimum(m, k).
- Now apply dynamic programming. Create a 2-d array dp[n + 1][m + 1] such that dp[i][j] will store the number of subsequences of length i whose first element begins after j-th element from arr[]. For example, dp[1][1] = 3 because it means number
of subsequences of length 1 whose first element starts after 1-st element of arr[] which are {3}, {3}, {5}.- Initialize first row of dp[][] to 1.
- Run two loops top to bottom and right to left inside of the former loop.
- If j > m – i that means there cannot be any such sequences due to lack of elements. So dp[i][j] = 0.
- Else, dp[i][j] = dp[i][j + 1] + arr[j] * dp[i – 1][j + 1] as the number will be number of already existing subsequences of length i plus the number of subsequences of length i – 1 multiplied by arr[j] due to repetition.
Below is the implementation of the above approach:
C++
// C++ implementation of the approach #include <bits/stdc++.h> using namespace std; // Returns number of subsequences // of maximum length k and // contains no repeated element int countSubSeq( int a[], int n, int k) { // Sort the array a[] sort(a, a + n); vector< int > arr; // Store the frequencies of all the // distinct element in the vector arr for ( int i = 0; i < n;) { int count = 1, x = a[i]; i++; while (i < n && a[i] == x) { count++; i++; } arr.push_back(count); } int m = arr.size(); n = min(m, k); // count is the the number // of such subsequences int count = 1; // Create a 2-d array dp[n+1][m+1] to // store the intermediate result int dp[n + 1][m + 1]; // Initialize the first row to 1 for ( int i = 0; i <= m; i++) dp[0][i] = 1; // Update the dp[][] array based // on the recurrence relation for ( int i = 1; i <= n; i++) { for ( int j = m; j >= 0; j--) { if (j > m - i) dp[i][j] = 0; else { dp[i][j] = dp[i][j + 1] + arr[j] * dp[i - 1][j + 1]; } } count = count + dp[i][0]; } // Return the number of subsequences return count; } // Driver code int main() { int a[] = { 2, 2, 3, 3, 5 }; int n = sizeof (a) / sizeof ( int ); int k = 3; cout << countSubSeq(a, n, k); return 0; } |
Java
// Java implementation of the approach import java.util.*; class GFG { // Returns number of subsequences // of maximum length k and // contains no repeated element static int countSubSeq( int a[], int n, int k) { // Sort the array a[] Arrays.sort(a); List<Integer> arr = new LinkedList<>(); // Store the frequencies of all the // distinct element in the vector arr for ( int i = 0 ; i < n;) { int count = 1 , x = a[i]; i++; while (i < n && a[i] == x) { count++; i++; } arr.add(count); } int m = arr.size(); n = Math.min(m, k); // count is the the number // of such subsequences int count = 1 ; // Create a 2-d array dp[n+1][m+1] to // store the intermediate result int [][]dp = new int [n + 1 ][m + 1 ]; // Initialize the first row to 1 for ( int i = 0 ; i <= m; i++) dp[ 0 ][i] = 1 ; // Update the dp[][] array based // on the recurrence relation for ( int i = 1 ; i <= n; i++) { for ( int j = m; j >= 0 ; j--) { if (j > m - i) dp[i][j] = 0 ; else { dp[i][j] = dp[i][j + 1 ] + arr.get(j) * dp[i - 1 ][j + 1 ]; } } count = count + dp[i][ 0 ]; } // Return the number of subsequences return count; } // Driver code public static void main(String[] args) { int a[] = { 2 , 2 , 3 , 3 , 5 }; int n = a.length; int k = 3 ; System.out.println(countSubSeq(a, n, k)); } } // This code is contributed by PrinciRaj1992 |
Python 3
# Python 3 implementation of the approach # Returns number of subsequences # of maximum length k and # contains no repeated element def countSubSeq(a, n, k): # Sort the array a[] a.sort(reverse = False ) arr = [] # Store the frequencies of all the # distinct element in the vector arr i = 0 while (i < n): count = 1 x = a[i] i + = 1 while (i < n and a[i] = = x): count + = 1 i + = 1 arr.append(count) m = len (arr) n = min (m, k) # count is the the number # of such subsequences count = 1 # Create a 2-d array dp[n+1][m+1] to # store the intermediate result dp = [[ 0 for i in range (m + 1 )] for j in range (n + 1 )] # Initialize the first row to 1 for i in range (m + 1 ): dp[ 0 ][i] = 1 # Update the dp[][] array based # on the recurrence relation for i in range ( 1 , n + 1 , 1 ): j = m while (j > = 0 ): if (j > m - i): dp[i][j] = 0 else : dp[i][j] = dp[i][j + 1 ] + \ arr[j] * dp[i - 1 ][j + 1 ] j - = 1 count = count + dp[i][ 0 ] # Return the number of subsequences return count # Driver code if __name__ = = '__main__' : a = [ 2 , 2 , 3 , 3 , 5 ] n = len (a) k = 3 print (countSubSeq(a, n, k)) # This code is contributed by Surendra_Gangwar |
C#
// C# implementation of the approach using System; using System.Collections.Generic; class GFG { // Returns number of subsequences // of maximum length k and // contains no repeated element static int countSubSeq( int []a, int n, int k) { // Sort the array a[] Array.Sort(a); List< int > arr = new List< int >(); int count, x; // Store the frequencies of all the // distinct element in the vector arr for ( int i = 0; i < n;) { count = 1; x = a[i]; i++; while (i < n && a[i] == x) { count++; i++; } arr.Add(count); } int m = arr.Count; n = Math.Min(m, k); // count is the the number // of such subsequences count = 1; // Create a 2-d array dp[n+1][m+1] to // store the intermediate result int [,]dp = new int [n + 1, m + 1]; // Initialize the first row to 1 for ( int i = 0; i <= m; i++) dp[0, i] = 1; // Update the dp[][] array based // on the recurrence relation for ( int i = 1; i <= n; i++) { for ( int j = m; j >= 0; j--) { if (j > m - i) dp[i, j] = 0; else { dp[i, j] = dp[i, j + 1] + arr[j] * dp[i - 1, j + 1]; } } count = count + dp[i, 0]; } // Return the number of subsequences return count; } // Driver code public static void Main(String[] args) { int []a = { 2, 2, 3, 3, 5 }; int n = a.Length; int k = 3; Console.WriteLine(countSubSeq(a, n, k)); } } // This code is contributed by 29AjayKumar |
18
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.