The "Count Sorted Vowel Strings" problem asks you to determine how many strings of length n
can be formed using only the vowels 'a'
, 'e'
, 'i'
, 'o'
, and 'u'
, such that the string is sorted lexicographically (each character is the same as or comes after the previous one in the alphabet).
Constraints:
n
characters long.n
(an integer, 1 ≤ n ≤ 50)
At first glance, one might consider generating all possible strings of length n
using the five vowels and then filtering those that are sorted. However, this brute-force approach quickly becomes infeasible as n
grows, since there are 5^n
possible strings.
To optimize, we recognize that the problem is about counting combinations, not generating them. Since the order of vowels in the string must be non-decreasing, this is akin to distributing n
indistinguishable balls (positions in the string) into 5 distinguishable bins (vowels, in sorted order), where each bin can hold zero or more balls. This is a classic combinatorics problem known as "stars and bars."
Let's break down the algorithm for counting sorted vowel strings:
n
vowels (with repetition) into 5 ordered slots (the vowels 'a'
, 'e'
, 'i'
, 'o'
, 'u'
).n
from a set of 5 items.n
from 5 types is C(n + 5 - 1, 5 - 1)
, or C(n+4, 4)
, where C
denotes the binomial coefficient ("n choose k").C(n+4, 4)
efficiently using either a loop, a helper function, or built-in math libraries.This approach is highly efficient because it avoids generating any strings and relies purely on mathematical calculation.
Let's walk through an example with n = 2
:
'a'
, 'e'
, 'i'
, 'o'
, 'u'
.
C(n+4, 4) = C(6, 4) = 15
.
O(5^n)
(generate all strings, check if sorted)O(5^n)
if storing all stringsO(1)
(just compute a binomial coefficient)O(1)
n
.
The "Count Sorted Vowel Strings" problem is a classic example of reducing a seemingly complex enumeration task to a simple combinatorial formula. By recognizing the connection to the "stars and bars" theorem, we can compute the result in constant time, regardless of the input size. This shift from brute-force to mathematical reasoning is a key insight in algorithm design, making the solution both elegant and efficient.
import math
class Solution:
def countVowelStrings(self, n: int) -> int:
# Using stars and bars: C(n+4, 4)
return math.comb(n + 4, 4)
class Solution {
public:
int countVowelStrings(int n) {
// C(n+4, 4) = (n+4)*(n+3)*(n+2)*(n+1)/24
return (n+4)*(n+3)*(n+2)*(n+1)/24;
}
};
class Solution {
public int countVowelStrings(int n) {
// C(n+4, 4) = (n+4)*(n+3)*(n+2)*(n+1)/24
return (n+4)*(n+3)*(n+2)*(n+1)/24;
}
}
var countVowelStrings = function(n) {
// C(n+4, 4) = (n+4)*(n+3)*(n+2)*(n+1)/24
return ((n+4)*(n+3)*(n+2)*(n+1))/24;
};