Number of distinct words of size N with at most K contiguous vowels

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> |
Output
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 |
Output
17576
Time Complexity: O(N * K)
Auxiliary Space: O(N * K)
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 zambiatek!
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 zambiatek!



