Count N-length strings consisting only of vowels sorted lexicographically
Last Updated :
24 Jun, 2022
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)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...