Given two integers N and K, the task is to find the number of distinct strings consisting of lowercase alphabets of length N that can be formed with at-most K contiguous vowels. As the answer may be too large, print answer%1000000007.
Input: N = 1, K = 0
Output: 21
Explanation: All the 21 consonants are there which has 0 contiguous vowels and are of length 1.Input: N = 1, K = 1
Output: 26
Approach: The idea to solve this problem is based on dynamic programming. Follow the steps below to solve the problem:Â
- Let dp[i][j] be the number of ways to make distinct strings of length i where the last j characters of the string are vowels.
- So the states of dynamic programming are:
- If j = 0, then dp[i][j] = (dp[i-1][0] + dp[i-1][1] +……+ dp[i-1][K])*21(represented by the integer variable sum) because the last added character should be a consonant than only the value of j will become 0 irrespective of its value on previous states.
- If i<j then dp[i][j] = 0. Since it is not possible to create a string containing j vowels and has a length less than j.
- If i == j, then dp[i][j] = 5i because the number of characters in the string is equal to the number of vowels, therefore all the characters should be vowels.
- If j<i then dp[i][j] = dp[i-1][j-1]*5 because a string of length i with last j characters vowel can be made only if the last character is the vowel and the string of length i-1 has last j – 1 character as vowels.
- Print the sum of dp[n][0] + dp[n][1] + …… + dp[n][K] as the answer.
Below is the implementation of the above Approach
C++
// C++ program for the above approach Â
#include <bits/stdc++.h> using namespace std; Â
// Power function to calculate // long powers with mod long long int power( long long int x, Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â long long int y, Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â long long int p) { Â Â Â Â long long int res = 1ll; Â
    x = x % p; Â
    if (x == 0)         return 0; Â
    while (y > 0) { Â
        if (y & 1)             res = (res * x) % p;         y = y >> 1;         x = (x * x) % p;     }     return res; } Â
// Function for finding number of ways to // create string with length N and atmost // K contiguous vowels int kvowelwords( int N, int K) { Â
    long long int i, j;     long long int MOD = 1000000007; Â
    // Array dp to store number of ways     long long int dp[N + 1][K + 1] = { 0 }; Â
    long long int sum = 1;     for (i = 1; i <= N; i++) { Â
        // dp[i][0] = (dp[i-1][0]+dp[i-1][1]..dp[i-1][k])*21         dp[i][0] = sum * 21;         dp[i][0] %= MOD; Â
        // Now setting sum to be dp[i][0]         sum = dp[i][0]; Â
        for (j = 1; j <= K; j++) {             // If j>i, no ways are possible to create             // a string with length i and vowel j             if (j > i)                 dp[i][j] = 0;             else if (j == i) {                 // If j = i all the character should                 // be vowel                 dp[i][j] = power(5ll, i, MOD);             }             else {                 // dp[i][j] relation with dp[i-1][j-1]                 dp[i][j] = dp[i - 1][j - 1] * 5;             } Â
            dp[i][j] %= MOD; Â
            // Adding dp[i][j] in the sum             sum += dp[i][j];             sum %= MOD;         }     } Â
    return sum; } // Driver Program int main() {     // Input     int N = 3;     int K = 3; Â
    // Function Call     cout << kvowelwords(N, K) << endl;     return 0; } |
C
// C program for the above approach #include <stdio.h> #include <string.h> Â
long long int dp[10000][10000]; Â
// Power function to calculate // long powers with mod long long int power( long long int x, Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â long long int y, Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â long long int p) { Â Â Â Â long long int res = 1ll; Â
    x = x % p; Â
    if (x == 0)         return 0; Â
    while (y > 0) { Â
        if (y & 1)             res = (res * x) % p;         y = y >> 1;         x = (x * x) % p;     }     return res; } Â
// Function for finding number of ways to // create string with length N and atmost // K contiguous vowels int kvowelwords( int N, int K) { Â
    long long int i, j;     long long int MOD = 1000000007;             long long int sum = 1;     for (i = 1; i <= N; i++) { Â
        // dp[i][0] = (dp[i-1][0]+dp[i-1][1]..dp[i-1][k])*21         dp[i][0] = sum * 21;         dp[i][0] %= MOD; Â
        // Now setting sum to be dp[i][0]         sum = dp[i][0]; Â
        for (j = 1; j <= K; j++) {             // If j>i, no ways are possible to create             // a string with length i and vowel j             if (j > i)                 dp[i][j] = 0;             else if (j == i) {                 // If j = i all the character should                 // be vowel                 dp[i][j] = power(5ll, i, MOD);             }             else {                 // dp[i][j] relation with dp[i-1][j-1]                 dp[i][j] = dp[i - 1][j - 1] * 5;             } Â
            dp[i][j] %= MOD; Â
            // Adding dp[i][j] in the sum             sum += dp[i][j];             sum %= MOD;         }     } Â
    return sum; } // Driver Program int main() {     // Input     int N = 3;     int K = 3;          memset (dp,0,N*K* sizeof ( long long int )); Â
    // Function Call     printf ( "%d" ,kvowelwords(N, K));     return 0; } |
Java
// Java program for the above approach class GFG{ Â
// Power function to calculate // long powers with mod static int power( int x, int y, int p) {     int res = 1 ;     x = x % p;       if (x == 0 )         return 0 ;       while (y > 0 )     {         if ((y & 1 ) != 0 )             res = (res * x) % p;                      y = y >> 1 ;         x = (x * x) % p;     }     return res; }   // Function for finding number of ways to // create string with length N and atmost // K contiguous vowels static int kvowelwords( int N, int K) {     int i, j;     int MOD = 1000000007 ;       // Array dp to store number of ways     int [][] dp = new int [N + 1 ][K + 1 ] ;       int sum = 1 ;     for (i = 1 ; i <= N; i++)     {                  // dp[i][0] = (dp[i-1][0]+dp[i-1][1]..dp[i-1][k])*21         dp[i][ 0 ] = sum * 21 ;         dp[i][ 0 ] %= MOD;           // Now setting sum to be dp[i][0]         sum = dp[i][ 0 ];           for (j = 1 ; j <= K; j++)         {                          // If j>i, no ways are possible to create             // a string with length i and vowel j             if (j > i)                 dp[i][j] = 0 ;                              else if (j == i)             {                                  // If j = i all the character should                 // be vowel                 dp[i][j] = power( 5 , i, MOD);             }             else             {                                  // dp[i][j] relation with dp[i-1][j-1]                 dp[i][j] = dp[i - 1 ][j - 1 ] * 5 ;             }               dp[i][j] %= MOD;               // Adding dp[i][j] in the sum             sum += dp[i][j];             sum %= MOD;         }     }     return sum; } Â
// Driver Code public static void main(String[] args) {          // Input     int N = 3 ;     int K = 3 ;       // Function Call     System.out.println( kvowelwords(N, K)); } } Â
// This code is contributed by target_2 |
Python3
# Python3 program for the above approach Â
# Power function to calculate # long powers with mod def power(x, y, p): Â Â Â Â Â Â Â Â Â res = 1 Â Â Â Â x = x % p Â
    if (x = = 0 ):         return 0 Â
    while (y > 0 ):         if (y & 1 ):             res = (res * x) % p                      y = y >> 1         x = (x * x) % p              return res Â
# Function for finding number of ways to # create string with length N and atmost # K contiguous vowels def kvowelwords(N, K): Â
    i, j = 0 , 0     MOD = 1000000007 Â
    # Array dp to store number of ways     dp = [[ 0 for i in range (K + 1 )]              for i in range (N + 1 )] Â
    sum = 1     for i in range ( 1 , N + 1 ):                  #dp[i][0] = (dp[i-1][0]+dp[i-1][1]..dp[i-1][k])*21         dp[i][ 0 ] = sum * 21         dp[i][ 0 ] % = MOD Â
        # Now setting sum to be dp[i][0]         sum = dp[i][ 0 ] Â
        for j in range ( 1 , K + 1 ):                          # If j>i, no ways are possible to create             # a string with length i and vowel j             if (j > i):                 dp[i][j] = 0             elif (j = = i):                                  # If j = i all the character should                 # be vowel                 dp[i][j] = power( 5 , i, MOD)             else :                                  # dp[i][j] relation with dp[i-1][j-1]                 dp[i][j] = dp[i - 1 ][j - 1 ] * 5 Â
            dp[i][j] % = MOD Â
            # Adding dp[i][j] in the sum             sum + = dp[i][j]             sum % = MOD Â
    return sum      # Driver Code if __name__ = = '__main__' :          # Input     N = 3     K = 3 Â
    # Function Call     print (kvowelwords(N, K)) Â
# This code is contributed by mohit kumar 29 |
C#
// C# program for the above approach using System; using System.Collections.Generic; Â
class GFG{ Â
// Power function to calculate // long powers with mod static int power( int x, int y, int p) {     int res = 1;     x = x % p;       if (x == 0)         return 0;       while (y > 0)     {         if ((y & 1) != 0)             res = (res * x) % p;                      y = y >> 1;         x = (x * x) % p;     }     return res; }   // Function for finding number of ways to // create string with length N and atmost // K contiguous vowels static int kvowelwords( int N, int K) {     int i, j;     int MOD = 1000000007;       // Array dp to store number of ways     int [,] dp = new int [N + 1, K + 1];       int sum = 1;     for (i = 1; i <= N; i++)     {                  // dp[i][0] = (dp[i-1, 0]+dp[i-1, 1]..dp[i-1][k])*21         dp[i, 0] = sum * 21;         dp[i, 0] %= MOD;           // Now setting sum to be dp[i][0]         sum = dp[i, 0];           for (j = 1; j <= K; j++)         {                          // If j>i, no ways are possible to create             // a string with length i and vowel j             if (j > i)                 dp[i, j] = 0;                              else if (j == i)             {                                  // If j = i all the character should                 // be vowel                 dp[i, j] = power(5, i, MOD);             }             else             {                                  // dp[i][j] relation with dp[i-1][j-1]                 dp[i, j] = dp[i - 1, j - 1] * 5;             }               dp[i, j] %= MOD;               // Adding dp[i][j] in the sum             sum += dp[i, j];             sum %= MOD;         }     }     return sum; } Â
// Driver Code public static void Main() {          // Input     int N = 3;     int K = 3;       // Function Call     Console.Write(kvowelwords(N, K)); } } Â
// This code is contributed by code_hunt |
Javascript
<script> Â
// JavaScript code for above approach Â
// Power function to calculate // long powers with mod function power(x, y, p) {     let res = 1;     x = x % p;       if (x == 0)         return 0;       while (y > 0)     {         if ((y & 1) != 0)             res = (res * x) % p;                      y = y >> 1;         x = (x * x) % p;     }     return res; }   // Function for finding number of ways to // create string with length N and atmost // K contiguous vowels function kvowelwords(N, K) {     let i, j;     let MOD = 1000000007;       // Array dp to store number of ways     let dp = new Array(N + 1)     // Loop to create 2D array using 1D array     for (i = 0; i < dp.length; i++) {         dp[i] = new Array(K + 1);     }       let sum = 1;     for (i = 1; i <= N; i++)     {                  // dp[i][0] = (dp[i-1][0]+dp[i-1][1]..dp[i-1][k])*21         dp[i][0] = sum * 21;         dp[i][0] %= MOD;           // Now setting sum to be dp[i][0]         sum = dp[i][0];           for (j = 1; j <= K; j++)         {                          // If j>i, no ways are possible to create             // a string with length i and vowel j             if (j > i)                 dp[i][j] = 0;                              else if (j == i)             {                                  // If j = i all the character should                 // be vowel                 dp[i][j] = power(5, i, MOD);             }             else             {                                  // dp[i][j] relation with dp[i-1][j-1]                 dp[i][j] = dp[i - 1][j - 1] * 5;             }               dp[i][j] %= MOD;               // Adding dp[i][j] in the sum             sum += dp[i][j];             sum %= MOD;         }     }     return sum; } Â
// Driver Code Â
    // Input     let N = 3;     let K = 3;       // Function Call     document.write( kvowelwords(N, K));          // This code is contributed by sanjoy_62. </script> |
17576
Time Complexity: O(N×K)
Auxiliary Space: O(N×K)
Approach 2: Recursion with Memoization
C++
#include <iostream> #include <vector> using namespace std; Â
const int MOD = 1e9 + 7; Â
int N, K; vector<vector<vector< int >>> memo; Â
int countWays( int pos, int vowels, bool prevVowel) { Â Â Â Â if (pos == N) return 1; Â Â Â Â if (memo[pos][vowels][prevVowel] != -1) return memo[pos][vowels][prevVowel]; Â
    int res = 0;     // Add a consonant     res = (res + 21 * countWays(pos + 1, 0, false )) % MOD;     // Add a vowel     if (prevVowel && vowels == K) {         res = (res + 0) % MOD;     } else {         res = (res + 5 * countWays(pos + 1, prevVowel ? vowels + 1 : 1, true )) % MOD;     } Â
    return memo[pos][vowels][prevVowel] = res; } Â
int kvowelwords( int n, int k) { Â Â Â Â N = n; K = k; Â Â Â Â memo.assign(N, vector<vector< int >>(K + 1, vector< int >(2, -1))); Â Â Â Â return countWays(0, 0, false ); } Â
int main() { Â Â Â Â cout << kvowelwords(3, 3) << endl; Â Â Â Â return 0; } |
Java
import java.util.Arrays; Â
public class KVowelWords { Â Â Â Â static final int MOD = 1000000007 ; Â Â Â Â static int N, K; Â Â Â Â static int [][][] memo; Â
    // Function to count the number of k-vowel words     static int countWays( int pos, int vowels, boolean prevVowel) {         if (pos == N) return 1 ;         if (memo[pos][vowels][prevVowel ? 1 : 0 ] != - 1 ) return memo[pos][vowels][prevVowel ? 1 : 0 ]; Â
        int res = 0 ;         // Add a consonant         res = (res + 21 * countWays(pos + 1 , 0 , false )) % MOD;         // Add a vowel         if (prevVowel && vowels == K) {             res = (res + 0 ) % MOD;         } else {             res = (res + 5 * countWays(pos + 1 , prevVowel ? vowels + 1 : 1 , true )) % MOD;         } Â
        return memo[pos][vowels][prevVowel ? 1 : 0 ] = res;     } Â
    // Function to compute the number of k-vowel words     static int kvowelwords( int n, int k) {         N = n; K = k;         memo = new int [N][K + 1 ][ 2 ];         for ( int i = 0 ; i < N; i++) {             for ( int j = 0 ; j <= K; j++) {                 Arrays.fill(memo[i][j], - 1 );             }         }         return countWays( 0 , 0 , false );     } Â
    public static void main(String[] args) {         System.out.println(kvowelwords( 3 , 3 ));     } } |
Python3
MOD = 10 * * 9 + 7 Â
def countWays(pos, vowels, prevVowel, N, K, memo): Â Â Â Â if pos = = N: Â Â Â Â Â Â Â Â return 1 Â
    if memo[pos][vowels][prevVowel] ! = - 1 :         return memo[pos][vowels][prevVowel] Â
    res = 0     # Add a consonant     res = (res + 21 * countWays(pos + 1 , 0 , False , N, K, memo)) % MOD     # Add a vowel     if prevVowel and vowels = = K:         res = (res + 0 ) % MOD     else :         res = (res + 5 * countWays(pos + 1 , vowels + 1 if prevVowel else 1 , True , N, K, memo)) % MOD Â
    memo[pos][vowels][prevVowel] = res     return res Â
def kvowelwords(n, k):     N = n     K = k     memo = [[[ - 1 for _ in range ( 2 )] for _ in range (K + 1 )] for _ in range (N)]     return countWays( 0 , 0 , False , N, K, memo) Â
if __name__ = = "__main__" : Â Â Â Â print (kvowelwords( 3 , 3 )) |
C#
using System; using System.Collections.Generic; Â
class Program { Â Â Â Â const int MOD = 1000000007; Â
    static int N, K;     static List<List<List< int >>> memo; Â
    static int CountWays( int pos, int vowels, bool prevVowel)     {         if (pos == N) return 1;         if (memo[pos][vowels][prevVowel ? 1 : 0] != -1) return memo[pos][vowels][prevVowel ? 1 : 0]; Â
        int res = 0;         // Add a consonant         res = (res + 21 * CountWays(pos + 1, 0, false )) % MOD;         // Add a vowel         if (prevVowel && vowels == K)         {             res = (res + 0) % MOD;         }         else         {             res = (res + 5 * CountWays(pos + 1, prevVowel ? vowels + 1 : 1, true )) % MOD;         } Â
        return memo[pos][vowels][prevVowel ? 1 : 0] = res;     } Â
    static int Kvowelwords( int n, int k)     {         N = n; K = k;         memo = new List<List<List< int >>>(N);         for ( int i = 0; i < N; i++)         {             memo.Add( new List<List< int >>(K + 1));             for ( int j = 0; j <= K; j++)             {                 memo[i].Add( new List< int > { -1, -1 });             }         }         return CountWays(0, 0, false );     } Â
    static void Main( string [] args)     {         Console.WriteLine(Kvowelwords(3, 3));     } } |
Javascript
const MOD = 1000000007; Â
let N, K; let memo; Â
// Function to count the ways to form words with specific vowel and consonant rules function countWays(pos, vowels, prevVowel) {     // Base case: If we've processed all positions in the word     if (pos === N) return 1; Â
    // If we have already computed this state, return it from memoization     if (memo[pos][vowels][prevVowel ? 1 : 0] !== -1) {         return memo[pos][vowels][prevVowel ? 1 : 0];     } Â
    let res = 0; Â
    // Add a consonant: There are 21 consonants available     res = (res + 21 * countWays(pos + 1, 0, false )) % MOD; Â
    // Add a vowel     if (prevVowel && vowels === K) {         // If the previous character was a vowel and we've already used K vowels, we can't add more         res = (res + 0) % MOD;     } else {         // Add a vowel: There are 5 vowels available         res = (res + 5 * countWays(pos + 1, prevVowel ? vowels + 1 : 1, true )) % MOD;     } Â
    // Memoize the result and return it     memo[pos][vowels][prevVowel ? 1 : 0] = res;     return res; } Â
// Function to calculate the count of words based on given parameters function kvowelWords(n, k) {     N = n; // Total word length     K = k; // Maximum allowed vowels Â
    // Initialize memoization table     memo = new Array(N).fill( null ).map(() => {         return new Array(K + 1).fill( null ).map(() => {             return [-1, -1];         });     }); Â
    // Start the recursive counting     return countWays(0, 0, false ); } Â
// Example usage: console.log(kvowelWords(3, 3)); // Output the count of words following the rules |
17576
Time Complexity: O(N * K)
Auxiliary Space: O(N * K)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!