Count unique subsequences of length K
Last Updated :
20 Dec, 2022
Given an array of N numbers and an integer K. The task is to print the number of unique subsequences possible of length K.
Examples:
Input : a[] = {1, 2, 3, 4}, k = 3
Output : 4.
Unique Subsequences are:
{1, 2, 3}, {1, 2, 4}, {1, 3, 4}, {2, 3, 4}
Input: a[] = {1, 1, 1, 2, 2, 2 }, k = 3
Output : 4
Unique Subsequences are
{1, 1, 1}, {1, 1, 2}, {1, 2, 2}, {2, 2, 2}
Approach:
There is a well-known formula for how many subsequences of fixed length K can be chosen from N unique objects. But the problem here has several differences. One among them is the order in subsequences is important and must be preserved as in the original sequence. For such a problem there can be no ready combinatorics formula because the results depend on the order of the original array.
The main idea is to deal recurrently by the length of the subsequence. On each recurrent step, move from the end to the beginning and count the unique combinations using the count of shorter unique combinations from the previous step. More strictly on every step j, we keep an array of length N and every element in the place p means how many unique subsequences with length j we found to the right of the element in place i, including i itself.
Below is the implementation of the above approach.
C++
#include <bits/stdc++.h>
using namespace std;
int solution(vector< int >& A, int k)
{
const int N = A.size();
if (N < k || N < 1 || k < 1)
return 0;
if (N == k)
return 1;
vector< int > v1(N, 0);
vector< int > v2(N, 0);
vector< int > v3(N, 0);
v2[N - 1] = 1;
v3[A[N - 1] - 1] = 1;
for ( int i = N - 2; i >= 0; i--) {
v2[i] = v2[i + 1];
if (v3[A[i] - 1] == 0) {
v2[i]++;
v3[A[i] - 1] = 1;
}
}
for ( int j = 1; j < k; j++) {
fill(v3.begin(), v3.end(), 0);
v1[N - 1] = 0;
for ( int i = N - 2; i >= 0; i--) {
v1[i] = v1[i + 1];
v1[i] = v1[i] + v2[i + 1];
v1[i] = v1[i] - v3[A[i] - 1];
v3[A[i] - 1] = v2[i + 1];
}
v2 = v1;
}
return v2[0];
}
void solve( int a[], int n, int k)
{
vector< int > v;
v.assign(a, a + n);
cout << solution(v, k);
}
int main()
{
int a[] = { 1, 2, 3, 4 };
int n = sizeof (a) / sizeof (a[0]);
int k = 3;
solve(a, n, k);
return 0;
}
|
Java
import java.util.*;
class GFG{
static int solution( int [] A, int N, int k)
{
if (N < k || N < 1 || k < 1 )
return 0 ;
if (N == k)
return 1 ;
int [] v1 = new int [N];
int [] v2 = new int [N];
int [] v3 = new int [N];
v2[N - 1 ] = 1 ;
v3[A[N - 1 ] - 1 ] = 1 ;
for ( int i = N - 2 ; i >= 0 ; i--)
{
v2[i] = v2[i + 1 ];
if (v3[A[i] - 1 ] == 0 )
{
v2[i]++;
v3[A[i] - 1 ] = 1 ;
}
}
for ( int j = 1 ; j < k; j++)
{
Arrays.fill(v3, 0 );
v1[N - 1 ] = 0 ;
for ( int i = N - 2 ; i >= 0 ; i--)
{
v1[i] = v1[i + 1 ];
v1[i] = v1[i] + v2[i + 1 ];
v1[i] = v1[i] - v3[A[i] - 1 ];
v3[A[i] - 1 ] = v2[i + 1 ];
}
}
return v2[ 0 ];
}
public static void main(String[] args)
{
int a[] = { 1 , 2 , 3 , 4 };
int n = a.length;
int k = 3 ;
System.out.print(solution(a, n, k));
}
}
|
Python3
def solution( A, k):
N = len (A)
if (N < k or N < 1 or k < 1 ):
return 0
if (N = = k):
return 1
v1 = [ 0 ] * (N)
v2 = [ 0 ] * N
v3 = [ 0 ] * N
v2[N - 1 ] = 1
v3[A[N - 1 ] - 1 ] = 1
for i in range (N - 2 , - 1 , - 1 ):
v2[i] = v2[i + 1 ]
if (v3[A[i] - 1 ] = = 0 ):
v2[i] + = 1
v3[A[i] - 1 ] = 1
for j in range ( 1 , k) :
v3 = [ 0 ] * N
v1[N - 1 ] = 0
for i in range ( N - 2 , - 1 , - 1 ) :
v1[i] = v1[i + 1 ]
v1[i] = v1[i] + v2[i + 1 ]
v1[i] = v1[i] - v3[A[i] - 1 ]
v3[A[i] - 1 ] = v2[i + 1 ]
for i in range ( len (v1)):
v2[i] = v1[i]
return v2[ 0 ]
def solve(a, n, k):
v = a
print ( solution(v, k))
if __name__ = = "__main__" :
a = [ 1 , 2 , 3 , 4 ]
n = len (a)
k = 3
solve(a, n, k)
|
C#
using System;
class GFG{
static int solution( int [] A, int N, int k)
{
if (N < k || N < 1 || k < 1)
return 0;
if (N == k)
return 1;
int [] v1 = new int [N];
int [] v2 = new int [N];
int [] v3 = new int [N];
v2[N - 1] = 1;
v3[A[N - 1] - 1] = 1;
for ( int i = N - 2; i >= 0; i--)
{
v2[i] = v2[i + 1];
if (v3[A[i] - 1] == 0)
{
v2[i]++;
v3[A[i] - 1] = 1;
}
}
for ( int j = 1; j < k; j++)
{
for ( int i = 0; i < v3.GetLength(0); i++)
v3[i] = 0;
v1[N - 1] = 0;
for ( int i = N - 2; i >= 0; i--)
{
v1[i] = v1[i + 1];
v1[i] = v1[i] + v2[i + 1];
v1[i] = v1[i] - v3[A[i] - 1];
v3[A[i] - 1] = v2[i + 1];
}
}
return v2[0];
}
public static void Main(String[] args)
{
int []a = { 1, 2, 3, 4 };
int n = a.Length;
int k = 3;
Console.Write(solution(a, n, k));
}
}
|
Javascript
<script>
function solution(A, N, K)
{
if (N < k || N < 1 || k < 1)
return 0;
if (N == k)
return 1;
let v1 = new Array(N);
let v2 = new Array(N);
let v3 = new Array(N);
for (let i = 0; i < N; i++)
{
v1[i] = 0;
v2[i] = 0;
v3[i] = 0;
}
v2[N - 1] = 1;
v3[A[N - 1] - 1] = 1;
for (let i = N - 2; i >= 0; i--)
{
v2[i] = v2[i + 1];
if (v3[A[i] - 1] == 0)
{
v2[i]++;
v3[A[i] - 1] = 1;
}
}
for (let j = 1; j < k; j++)
{
for (let i = 0; i < v3.length; i++)
{
v3[i] = 0;
}
v1[N - 1] = 0;
for (let i = N - 2; i >= 0; i--)
{
v1[i] = v1[i + 1];
v1[i] = v1[i] + v2[i + 1];
v1[i] = v1[i] - v3[A[i] - 1];
v3[A[i] - 1] = v2[i + 1];
}
}
return v2[0];
}
let a = [ 1, 2, 3, 4 ];
let n = a.length;
let k = 3;
document.write(solution(a, n, k));
</script>
|
Complexity Analysis:
- Time Complexity: O(N * K)
- Auxiliary Space: O(N)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...