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 modlong 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 vowelsint 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 Programint 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 modlong 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 vowelsint 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 Programint 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 approachclass GFG{Â
// Power function to calculate// long powers with modstatic 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 vowelsstatic 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 Codepublic 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 moddef 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 vowelsdef 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 Codeif __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 approachusing System;using System.Collections.Generic;Â
class GFG{Â
// Power function to calculate// long powers with modstatic 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 vowelsstatic 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 Codepublic 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 modfunction 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 vowelsfunction 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 rulesfunction 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 parametersfunction 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!
