Given an integer N, the task is to count all possible strings of length N consisting of vowels {a, e, i, o, u} that can be formed such that each string is sorted in lexicographical order.
Examples:
Input: N = 2
Output: 15
Explanation: The strings of length 2 which are sorted in lexicographical order are [“aa”, “ae”, “ai”, “ao”, “au”, “ee”, “ei”, “eo”, “eu”, “ii”, “io”, “iu”, “oo”, “ou”, “uu”].
Input: N = 1
Output: 5
Explanation: The strings of length 1 which are sorted in lexicographical order are [“a”, “e”, “i”, “o”, “u”].
Naive Approach: The simplest approach is to generate all possible strings of length N such that each string is sorted in lexicographical order. Print the count obtained after completing the steps.
Recursive Approach: Keep track of the vowel added to the string so that the next vowel added to the string is always Lexicographically greater.
C++
#include <iostream>
using namespace std;
int countstrings( int n, int start)
{
if (n == 0) {
return 1;
}
int cnt = 0;
for ( int i = start; i < 5; i++) {
cnt += countstrings(n - 1, i);
}
return cnt;
}
int countVowelStrings( int n)
{
return countstrings(n, 0);
}
int main()
{
int n = 2;
cout << countVowelStrings(n);
return 0;
}
|
C
#include <stdio.h>
int countstrings( int n, int start)
{
if (n == 0) {
return 1;
}
int cnt = 0;
for ( int i = start; i < 5; i++) {
cnt += countstrings(n - 1, i);
}
return cnt;
}
int countVowelStrings( int n)
{
return countstrings(n, 0);
}
int main() {
int n = 2;
printf ( "%d" ,countVowelStrings(n));
return 0;
}
|
Java
import java.util.*;
public class Main
{
static int countstrings( int n, int start)
{
if (n == 0 ) {
return 1 ;
}
int cnt = 0 ;
for ( int i = start; i < 5 ; i++)
{
cnt += countstrings(n - 1 , i);
}
return cnt;
}
static int countVowelStrings( int n)
{
return countstrings(n, 0 );
}
public static void main(String[] args) {
int n = 2 ;
System.out.print(countVowelStrings(n));
}
}
|
Python3
def countstrings(n, start):
if n = = 0 :
return 1
cnt = 0
for i in range (start, 5 ):
cnt + = countstrings(n - 1 , i)
return cnt
def countVowelStrings(n):
return countstrings(n, 0 )
n = 2
print (countVowelStrings(n))
|
C#
using System;
using System.Collections.Generic;
class GFG {
static int countstrings( int n, int start)
{
if (n == 0) {
return 1;
}
int cnt = 0;
for ( int i = start; i < 5; i++)
{
cnt += countstrings(n - 1, i);
}
return cnt;
}
static int countVowelStrings( int n)
{
return countstrings(n, 0);
}
static void Main() {
int n = 2;
Console.Write(countVowelStrings(n));
}
}
|
Javascript
<script>
function countstrings(n, start)
{
if (n == 0) {
return 1;
}
let cnt = 0;
for (let i = start; i < 5; i++)
{
cnt += countstrings(n - 1, i);
}
return cnt;
}
function countVowelStrings(n)
{
return countstrings(n, 0);
}
let n = 2;
document.write(countVowelStrings(n));
</script>
|
Time Complexity: O(N!)
Auxiliary Space: O(1)
Efficient Approach: To optimize the above approach, the idea is to use Dynamic Programming. Below are some observations to solve the given problem:
- Count of lexicographically sorted strings of length 1 starting from characters a, e, i, o, and u is 1.
- Count of strings of length 2 that are in lexicographical order starting from characters a, e, i, o, and u is given by:
- The count of lexicographically sorted strings of length 2 starting from characters a is given by the count of the lexicographical strings of length 1 starting from character greater than or equal to a. Therefore, the count is 5.
- The count of lexicographically sorted strings of length 2 starting from characters e is given by the count of the lexicographical strings of length 1 starting from character greater than or equal to e. Therefore, the count is 4.
- The count of lexicographically sorted strings of length 2 starting from characters i is given by the count of the lexicographical strings of length 1 starting from character greater than or equal to i. Therefore, the count is 3.
- The count of lexicographically sorted strings of length 2 starting from characters o is given by the count of the lexicographical strings of length 1 starting from character greater than or equal to o. Therefore, the count is 2.
- The count of lexicographically sorted strings of length 2 starting from characters u is given by the count of the lexicographical strings of length 1 starting from character greater than or equal to u. Therefore, the count is 1.
- Therefore, the total count of strings length 2 is given by: 5 + 4 + 3 + 2 + 1 = 15.
- By observing the above pattern the count of strings of length N starting from each vowel character ch is given by the sum of the count of the lexicographical strings of length (N – 1) starting from character greater than or equal to ch.
Follow the steps below to solve the problem:
- Create a 2D array, dp[N + 1][6] where dp[i][j] represents the number of lexicographically sorted strings of length i that can be constructed using the first j vowels and initialize dp[1][1] with 1.
- Iterate over the first row using variable j, set dp[1][j] = dp[1][j – 1] + 1 as the string of length 1 are always sorted in lexicographically order.
- Traverse the 2D array dp[][] and update each dp state as dp[i][j] = dp[i][j – 1] + dp[i – 1][j], where dp[i][j – 1] will give the count of lexicographical string length N and dp[i – 1][j] will give the count of lexicographical string length (N – 1).
- After the above steps, print the value of dp[N][5] as the total count of resultant strings.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int findNumberOfStrings( int n)
{
vector<vector< int > > DP(n + 1,
vector< int >(6));
DP[1][1] = 1;
for ( int i = 1; i < n + 1; i++) {
for ( int j = 1; j < 6; j++) {
if (i == 1) {
DP[i][j] = DP[i][j - 1] + 1;
}
else {
DP[i][j] = DP[i][j - 1]
+ DP[i - 1][j];
}
}
}
return DP[n][5];
}
int main()
{
int N = 2;
cout << findNumberOfStrings(N);
return 0;
}
|
C
#include <stdio.h>
int findNumberOfStrings( int n)
{
int DP[n + 1][6];
DP[1][1] = 1;
for ( int i = 1; i < n + 1; i++) {
for ( int j = 1; j < 6; j++) {
if (i == 1)
DP[i][j] = DP[i][j - 1] + 1;
else
DP[i][j] = DP[i][j - 1] + DP[i - 1][j];
}
}
return DP[n][5];
}
int main() {
int N = 2;
printf ( "%d" ,findNumberOfStrings(N));
return 0;
}
|
Java
import java.util.*;
class GFG{
static int findNumberOfStrings( int n)
{
int DP[][] = new int [n + 1 ][ 6 ];
DP[ 1 ][ 1 ] = 1 ;
for ( int i = 1 ; i < n + 1 ; i++)
{
for ( int j = 1 ; j < 6 ; j++)
{
if (i == 1 )
{
DP[i][j] = DP[i][j - 1 ] + 1 ;
}
else
{
DP[i][j] = DP[i][j - 1 ] +
DP[i - 1 ][j];
}
}
}
return DP[n][ 5 ];
}
public static void main(String[] args)
{
int N = 2 ;
System.out.print(findNumberOfStrings(N));
}
}
|
Python3
def findNumberOfStrings(n):
DP = [[ 0 for i in range ( 6 )]
for i in range (n + 1 )]
DP[ 1 ][ 1 ] = 1
for i in range ( 1 , n + 1 ):
for j in range ( 1 , 6 ):
if (i = = 1 ):
DP[i][j] = DP[i][j - 1 ] + 1
else :
DP[i][j] = DP[i][j - 1 ] + DP[i - 1 ][j]
return DP[n][ 5 ]
if __name__ = = '__main__' :
N = 2
print (findNumberOfStrings(N))
|
C#
using System;
class GFG{
static int findNumberOfStrings( int n)
{
int [,] DP = new int [n + 1, 6];
DP[1, 1] = 1;
for ( int i = 1; i < n + 1; i++)
{
for ( int j = 1; j < 6; j++)
{
if (i == 1)
{
DP[i, j] = DP[i, j - 1] + 1;
}
else
{
DP[i, j] = DP[i, j - 1] +
DP[i - 1, j];
}
}
}
return DP[n, 5];
}
public static void Main( string [] args)
{
int N = 2;
Console.Write(findNumberOfStrings(N));
}
}
|
Javascript
<script>
function findNumberOfStrings(n)
{
let DP = new Array(n + 1);
for ( var i = 0; i < DP.length; i++) {
DP[i] = new Array(2);
}
for ( var i = 0; i < DP.length; i++) {
for ( var j = 0; j < DP.length; j++) {
DP[i][j] = 0;
}
}
DP[1][1] = 1;
for (let i = 1; i < n + 1; i++)
{
for (let j = 1; j < 6; j++)
{
if (i == 1)
{
DP[i][j] = DP[i][j - 1] + 1;
}
else
{
DP[i][j] = DP[i][j - 1] +
DP[i - 1][j];
}
}
}
return DP[n][5];
}
let N = 2;
document.write(findNumberOfStrings(N));
</script>
|
Time Complexity: O(N*5)
Auxiliary Space: O(N*5)
Efficient Approach: The above approach can further be simplified to linear time and constant space.
Here are some of the observations for different lengths of strings:-
N |
Number of strings starting with |
Total Possible strings |
‘a’ |
‘e’ |
‘i’ |
‘o’ |
‘u’ |
1 |
1 |
1 |
1 |
1 |
1 |
5 |
2 |
5 |
4 |
3 |
2 |
1 |
15 |
3 |
15 |
10 |
6 |
3 |
1 |
35 |
4 |
35 |
20 |
10 |
4 |
1 |
70 |
It is seen that for each value of N, number of strings possible is dependent on the previous value of N (N-1).
Value of any column in the Nth row is the sum of all columns in the (N-1)th row, starting from right hand side upto that column number.
C++
#include <bits/stdc++.h>
using namespace std;
int findNumberOfStrings( int N)
{
vector< int > counts(5, 1);
for ( int i = 2; i <= N; i++) {
for ( int j = 3; j >= 0; j--)
counts[j] += counts[j + 1];
}
int ans = 0;
for ( auto c : counts)
ans += c;
return ans;
}
int main()
{
int N = 2;
cout << findNumberOfStrings(N);
return 0;
}
|
C
#include <stdio.h>
int findNumberOfStrings( int N)
{
int counts[5];
for ( int i = 0; i < 5;i++)
counts[i] = 1;
for ( int i = 2; i <= N; i++) {
for ( int j = 3; j >= 0; j--)
counts[j] += counts[j + 1];
}
int ans = 0;
for ( int c = 0; c < 5; c++)
ans += counts;
return ans;
}
int main()
{
int N = 2;
printf ( "%d" ,findNumberOfStrings(N));
return 0;
}
|
Java
import java.util.*;
public class Main
{
static int findNumberOfStrings( int N)
{
Vector<Integer> counts = new Vector<Integer>();
for ( int i = 0 ; i < 5 ; i++)
{
counts.add( 1 );
}
for ( int i = 2 ; i <= N; i++) {
for ( int j = 3 ; j >= 0 ; j--)
counts.set(j, counts.get(j) + counts.get(j + 1 ));
}
int ans = 0 ;
for (Integer c : counts)
ans += c;
return ans;
}
public static void main(String[] args) {
int N = 2 ;
System.out.print(findNumberOfStrings(N));
}
}
|
Python3
def findNumberOfStrings(N):
counts = []
for i in range ( 5 ):
counts.append( 1 )
for i in range ( 2 , N + 1 ):
for j in range ( 3 , - 1 , - 1 ):
counts[j] + = counts[j + 1 ]
ans = 0
for c in counts:
ans + = c
return ans
N = 2
print (findNumberOfStrings(N))
|
C#
using System;
using System.Collections;
using System.Collections.Generic;
class GFG
{
static int findNumberOfStrings( int N)
{
List< int > counts = new List< int >();
for ( int i = 0 ; i < 5 ; i++)
{
counts.Add(1);
}
for ( int i = 2 ; i <= N ; i++) {
for ( int j = 3 ; j >= 0 ; j--){
counts[j] = counts[j] + counts[j+1];
}
}
int ans = 0;
foreach ( int c in counts)
ans += c;
return ans;
}
public static void Main( string [] args){
int N = 2;
Console.Write(findNumberOfStrings(N));
}
}
|
Javascript
<script>
function findNumberOfStrings(N)
{
let counts = [1, 1, 1, 1, 1];
for (let i = 2; i < N + 1; i++)
for (let j = 3; j >= 0; j--)
counts[j] += counts[j + 1]
let ans = 0;
for (let c in counts)
ans = ans + counts;
return ans
}
let N = 2
document.write(findNumberOfStrings(N));
</script>
|
Time Complexity: O(5*N)
Space Complexity: O(1)
Efficient Approach: The same idea of the above dp approach can be implemented in constant time and constant space.
C++
#include <bits/stdc++.h>
using namespace std;
int findNumberOfStrings( int n)
{
return (n+1)*(n+2)*(n+3)*(n+4)/24;
}
int main()
{
int N = 2;
cout << findNumberOfStrings(N);
return 0;
}
|
C
#include <stdio.h>
int findNumberOfStrings( int n)
{
return (n+1)*(n+2)*(n+3)*(n+4)/24;
}
int main()
{
int N = 2;
printf ( "%d" , findNumberOfStrings(N));
return 0;
}
|
Java
import java.util.*;
class GFG{
static int findNumberOfStrings( int n)
{
return (n+ 1 )*(n+ 2 )*(n+ 3 )*(n+ 4 )/ 24 ;
}
public static void main(String[] args)
{
int N = 2 ;
System.out.print(findNumberOfStrings(N));
}
}
|
Python
def findNumberOfStrings(n):
return int ((n + 1 ) * (n + 2 ) * (n + 3 ) * (n + 4 ) / 24 )
if __name__ = = '__main__' :
N = 2
print (findNumberOfStrings(N))
|
C#
using System;
class GFG{
static int findNumberOfStrings( int n)
{
return (n+1)*(n+2)*(n+3)*(n+4)/24;
}
public static void Main( string [] args)
{
int N = 2;
Console.Write(findNumberOfStrings(N));
}
}
|
Javascript
<script>
function findNumberOfStrings(n)
{
return (n+1)*(n+2)*(n+3)*(n+4)/24;
}
let N = 2;
document.write(findNumberOfStrings(N));
</script>
|
Time Complexity: O(1)
Auxiliary Space: O(1)
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!