Count all increasing subsequences
Last Updated :
18 Dec, 2023
We are given an array of digits (values lie in range from 0 to 9). The task is to count all the sub sequences possible in array such that in each subsequence every digit is greater than its previous digits in the subsequence.
Examples:
Input : arr[] = {1, 2, 3, 4}
Output: 15
Explanation: There are 15 increasing subsequences
{1}, {2}, {3}, {4}, {1,2}, {1,3}, {1,4},
{2,3}, {2,4}, {3,4}, {1,2,3}, {1,2,4},
{1,3,4}, {2,3,4}, {1,2,3,4}
Input : arr[] = {4, 3, 6, 5}
Output: 8
Explanation: Sub-sequences are {4}, {3}, {6}, {5}, {4,6}, {4,5}, {3,6}, {3,5}
Input: arr[] = {3, 2, 4, 5, 4}
Output: 14
Explanation: Sub-sequences are {3}, {2}, {4}, {3,4},
{2,4}, {5}, {3,5}, {2,5}, {4,5}
{3,4,5},{2,4,5},{4}, {3,4}, {2,4}
A Simple Solution is to use Dynamic Programming Solution of Longest Increasing Subsequence (LIS) problem. Like LIS problem, we first compute count of increasing subsequences ending at every index. Finally, we return sum of all values (In LCS problem, we return max of all values).
// We count all increasing subsequences ending at every
// index i
subCount(i) = Count of increasing subsequences ending
at arr[i].
// Like LCS, this value can be recursively computed
subCount(i) = 1 + ? subCount(j)
where j is index of all elements
such that arr[j] < arr[i] and j < i.
1 is added as every element itself is a subsequence
of size 1.
// Finally we add all counts to get the result.
Result = ? subCount(i)
where i varies from 0 to n-1.
Illustration:
For example, arr[] = {3, 2, 4, 5, 4}
// There are no smaller elements on left of arr[0]
// and arr[1]
subCount(0) = 1
subCount(1) = 1
// Note that arr[0] and arr[1] are smaller than arr[2]
subCount(2) = 1 + subCount(0) + subCount(1) = 3
subCount(3) = 1 + subCount(0) + subCount(1) + subCount(2)
= 1 + 1 + 1 + 3
= 6
subCount(3) = 1 + subCount(0) + subCount(1)
= 1 + 1 + 1
= 3
Result = subCount(0) + subCount(1) + subCount(2) + subCount(3)
= 1 + 1 + 3 + 6 + 3
= 14.
Time Complexity : O(n2)
Auxiliary Space : O(n)
Refer this for implementation.
Method 2 (Efficient)
The above solution doesn’t use the fact that we have only 10 possible values in given array. We can use this fact by using an array count[] such that count[d] stores current count digits smaller than d.
For example, arr[] = {3, 2, 4, 5, 4}
// We create a count array and initialize it as 0.
count[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
// Note that here value is used as index to store counts
count[3] += 1 // i = 0, arr[0] = 3
= 1
count[2] += 1 // i = 1, arr[1] = 2
= 1
// Let us compute count for arr[2] which is 4
count[4] += 1 + count[3] + count[2]
+= 1 + 1 + 1
= 3
// Let us compute count for arr[3] which is 5
count[5] += 1 + count[3] + count[2] + count[4]
+= 1 + 1 + 1 + 3
= 6
// Let us compute count for arr[4] which is 4
count[4] += 1 + count[0] + count[1]
+= 1 + 1 + 1
+= 3
= 3 + 3
= 6
Note that count[] = {0, 0, 1, 1, 6, 6, 0, 0, 0, 0}
Result = count[0] + count[1] + ... + count[9]
= 1 + 1 + 6 + 6 {count[2] = 1, count[3] = 1
count[4] = 6, count[5] = 6}
= 14
Below is the implementation of above idea.
C++
#include<bits/stdc++.h>
using namespace std;
int countSub( int arr[], int n)
{
int count[10] = {0};
for ( int i=0; i<n; i++)
{
for ( int j=arr[i]-1; j>=0; j--)
count[arr[i]] += count[j];
count[arr[i]]++;
}
int result = 0;
for ( int i=0; i<10; i++)
result += count[i];
return result;
}
int main()
{
int arr[] = {3, 2, 4, 5, 4};
int n = sizeof (arr)/ sizeof (arr[0]);
cout << countSub(arr,n);
return 0;
}
|
Java
import java.io.*;
class GFG {
static int countSub( int arr[], int n)
{
int count[] = new int [ 10 ];
for ( int i = 0 ; i < n; i++)
{
for ( int j = arr[i] - 1 ; j >= 0 ; j--)
count[arr[i]] += count[j];
count[arr[i]]++;
}
int result = 0 ;
for ( int i = 0 ; i < 10 ; i++)
result += count[i];
return result;
}
public static void main(String[] args)
{
int arr[] = { 3 , 2 , 4 , 5 , 4 };
int n = arr.length;
System.out.println(countSub(arr,n));
}
}
|
Python3
def countSub(arr, n):
count = [ 0 for i in range ( 10 )]
for i in range (n):
for j in range (arr[i] - 1 , - 1 , - 1 ):
count[arr[i]] + = count[j]
count[arr[i]] + = 1
result = 0
for i in range ( 10 ):
result + = count[i]
return result
arr = [ 3 , 2 , 4 , 5 , 4 ]
n = len (arr)
print (countSub(arr, n))
|
C#
using System;
class GFG {
static int countSub( int []arr, int n)
{
int []count = new int [10];
for ( int i = 0; i < n; i++)
{
for ( int j = arr[i] - 1; j >= 0; j--)
count[arr[i]] += count[j];
count[arr[i]]++;
}
int result = 0;
for ( int i = 0; i < 10; i++)
result += count[i];
return result;
}
public static void Main()
{
int []arr = {3, 2, 4, 5, 4};
int n = arr.Length;
Console.WriteLine(countSub(arr,n));
}
}
|
Javascript
<script>
function countSub(arr, n)
{
let count = new Array(10).fill(0);
for (let i = 0; i < n; i++)
{
for (let j = arr[i] - 1; j >= 0; j--)
count[arr[i]] += count[j];
count[arr[i]]++;
}
let result = 0;
for (let i = 0; i < 10; i++)
result += count[i];
return result;
}
let arr = [ 3, 2, 4, 5, 4 ];
let n = arr.length;
document.write(countSub(arr, n));
</script>
|
Time Complexity : O(n) Note that the inner loop runs at most 10 times.
Auxiliary Space : O(1) Note that count has at-most 10 elements.
This article is contributed by Shashank Mishra ( Gullu ).
Share your thoughts in the comments
Please Login to comment...