3813. Vowel-Consonant Score
Problem Description
You are given a string s made up of lowercase English letters, spaces, and digits.
Let v be the number of vowels in s and c be the number of consonants in s.
- A vowel is one of the letters
'a','e','i','o', or'u'. - Any other letter in the English alphabet is considered a consonant.
Note that spaces and digits are not counted as vowels or consonants.
The score of the string s is defined as follows:
- If
c > 0, thenscore = floor(v / c), wherefloormeans rounding down to the nearest integer. - Otherwise (when
c == 0), thescore = 0.
Your task is to return an integer representing the score of the string s.
How We Pick the Algorithm
Why Simulation / Basic DSA?
This problem maps to Simulation / Basic DSA through a short path in the full flowchart.
Counting vowels and consonants in a string and computing the floor division score is a direct simulation of the problem statement.
Open in FlowchartIntuition
The score depends entirely on two quantities: the number of vowels v and the number of consonants c. So the natural first step is to figure out these two counts.
To do this, we look at each character in the string one by one. We only care about letters of the alphabet, so we skip over spaces and digits. For every letter we encounter, we check whether it is one of 'a', 'e', 'i', 'o', 'u'. If it is, it counts as a vowel; if not, it is a consonant.
A handy trick is to first count all letters (both vowels and consonants together) and separately count just the vowels. Then the number of consonants is simply total letters - vowels. This avoids writing a separate condition for consonants.
Once we have v and c, the score follows directly from the rule given:
- If
c == 0, there are no consonants to divide by, so the score is0. - Otherwise, the score is
v // c, where//performs integer division, which already rounds down to the nearest integer just likefloor(v / c).
This gives us a clean single-pass approach over the string.
Solution Approach
Solution 1: Counting
We use a simple counting approach with a single pass over the string. No extra data structures are needed beyond two integer counters.
-
Initialize two counters:
v = 0for vowels andc = 0for letters. -
Iterate through every character
chin the strings:- Use
ch.isalpha()to check whetherchis a letter. This automatically skips spaces and digits. - If
chis a letter, incrementc(counting it as a letter for now). - Then check if
chis in the set"aeiou". If so, incrementvas well.
- Use
-
After the loop,
cholds the count of all letters, whilevholds the count of vowels. To get the actual number of consonants, subtract the vowels:c -= v. -
Finally, compute the score based on the problem rule:
- If
c == 0, return0since there are no consonants to divide by. - Otherwise, return
v // c, where integer division//naturally rounds down to the nearest integer, matchingfloor(v / c).
- If
The time complexity is O(n), where n is the length of the string, since we scan each character once. The space complexity is O(1), as we only use a constant number of variables.
Example Walkthrough
Let's trace through the solution using the string s = "hi3 boa".
We start with two counters: v = 0 (vowels) and c = 0 (letters). We then scan each character one by one.
| Character | isalpha()? | In "aeiou"? | Action | v | c |
|---|---|---|---|---|---|
'h' | Yes | No | c += 1 | 0 | 1 |
'i' | Yes | Yes | c += 1, v += 1 | 1 | 2 |
'3' | No | — | skip | 1 | 2 |
' ' | No | — | skip | 1 | 2 |
'b' | Yes | No | c += 1 | 1 | 3 |
'o' | Yes | Yes | c += 1, v += 1 | 2 | 4 |
'a' | Yes | Yes | c += 1, v += 1 | 3 | 5 |
After the loop, v = 3 and c = 5, but remember c currently counts all letters, not just consonants.
Step — convert c to consonant count:
We subtract the vowels from the total letters:
c -= v → c = 5 - 3 = 2.
So we have v = 3 vowels (i, o, a) and c = 2 consonants (h, b). Notice the digit '3' and the space were correctly ignored.
Step — compute the score:
Since c = 2 > 0, we apply integer division:
score = v // c = 3 // 2 = 1.
The integer division // rounds down automatically, matching floor(3 / 2) = floor(1.5) = 1.
Result: the function returns 1.
As a quick edge-case check, consider s = "aei 9". Here every letter is a vowel, so after the scan v = 3 and c = 3, then c -= v gives c = 0. Because there are no consonants, we return 0 directly, avoiding division by zero.
Solution Implementation
1class Solution:
2 def vowelConsonantScore(self, s: str) -> int:
3 # Count of vowels found in the string
4 vowel_count = 0
5 # Count of consonants found in the string
6 consonant_count = 0
7
8 # Define the set of vowels for quick membership checking
9 vowels = set("aeiou")
10
11 # Iterate over each character in the input string
12 for ch in s:
13 # Only consider alphabetic characters (ignore digits, symbols, etc.)
14 if ch.isalpha():
15 if ch in vowels:
16 # Character is a vowel
17 vowel_count += 1
18 else:
19 # Character is a consonant
20 consonant_count += 1
21
22 # Avoid division by zero: if there are no consonants, return 0
23 if consonant_count == 0:
24 return 0
25
26 # Return the integer division of vowel count by consonant count
27 return vowel_count // consonant_count
281class Solution {
2 public int vowelConsonantScore(String s) {
3 // Count of vowels found in the string
4 int vowelCount = 0;
5 // Count of letters (later reduced to consonants only)
6 int letterCount = 0;
7
8 // Iterate over every character in the string
9 for (int i = 0; i < s.length(); i++) {
10 char ch = s.charAt(i);
11
12 // Only consider alphabetic characters
13 if (Character.isLetter(ch)) {
14 letterCount++;
15
16 // Check if the current character is a vowel
17 if ("aeiou".indexOf(ch) != -1) {
18 vowelCount++;
19 }
20 }
21 }
22
23 // Subtract vowels from total letters to get the consonant count
24 int consonantCount = letterCount - vowelCount;
25
26 // Avoid division by zero; return the integer ratio of vowels to consonants
27 return consonantCount == 0 ? 0 : vowelCount / consonantCount;
28 }
29}
301class Solution {
2public:
3 int vowelConsonantScore(string s) {
4 int vowelCount = 0; // Number of vowels in the string
5 int consonantCount = 0; // Number of consonants in the string
6
7 // Iterate over each character in the string
8 for (char ch : s) {
9 // Only consider alphabetic characters
10 if (isalpha(static_cast<unsigned char>(ch))) {
11 // Convert to lowercase so the comparison is case-insensitive
12 char lower = static_cast<char>(tolower(static_cast<unsigned char>(ch)));
13
14 // Check whether the character is a vowel
15 if (string("aeiou").find(lower) != string::npos) {
16 ++vowelCount;
17 } else {
18 ++consonantCount;
19 }
20 }
21 }
22
23 // Avoid division by zero: if there are no consonants, the score is 0
24 return consonantCount == 0 ? 0 : vowelCount / consonantCount;
25 }
26};
271/**
2 * Calculates a score based on the ratio of vowels to consonants in a string.
3 * Only alphabetic characters are considered; all other characters are ignored.
4 *
5 * The score is computed as floor(vowelCount / consonantCount).
6 * If there are no consonants, the function returns 0 to avoid division by zero.
7 *
8 * @param s - The input string to evaluate.
9 * @returns The integer score derived from the vowel-to-consonant ratio.
10 */
11function vowelConsonantScore(s: string): number {
12 // Track the number of vowels and the total number of letters.
13 let vowelCount = 0;
14 let letterCount = 0;
15
16 // Iterate over each character in the string.
17 for (const char of s) {
18 // Only process alphabetic characters (a-z, A-Z).
19 if (/[a-zA-Z]/.test(char)) {
20 letterCount++;
21
22 // Check whether the current character is a lowercase vowel.
23 if ('aeiou'.includes(char)) {
24 vowelCount++;
25 }
26 }
27 }
28
29 // Derive the consonant count by subtracting vowels from the total letters.
30 const consonantCount = letterCount - vowelCount;
31
32 // Guard against division by zero, then return the floored ratio.
33 return consonantCount === 0 ? 0 : Math.floor(vowelCount / consonantCount);
34}
35Time and Space Complexity
-
Time Complexity:
O(n), wherenis the length of the strings. The code iterates through each character of the string exactly once in theforloop. For each character, it performs constant-time operations (isalpha()check, membership checkch in "aeiou"against a fixed-size string, and increments). Therefore, the total time grows linearly with the length of the string. -
Space Complexity:
O(1). The algorithm uses only a constant amount of extra space, namely the variablesvandcto track the counts of vowels and consonants, along with the loop variablech. No additional data structures that scale with the input size are used.
Pattern Learn more about how to find time and space complexity quickly.
Common Pitfalls
Pitfall 1: Forgetting to Handle the c == 0 Case (Division by Zero)
The most common mistake is computing vowel_count // consonant_count directly without first checking whether consonant_count is zero. When the string contains no consonants (e.g., "aeiou", "a1 e2", or "12345"), this triggers a ZeroDivisionError in Python and crashes the program.
Why it happens: Developers focus on the main formula floor(v / c) and overlook the special rule that score = 0 when c == 0.
Example that breaks:
s = "aeiou" # 5 vowels, 0 consonants # vowel_count // consonant_count -> 5 // 0 -> ZeroDivisionError
Solution: Always guard the division with an explicit check, as the provided code does:
if consonant_count == 0: return 0 return vowel_count // consonant_count
Pitfall 2: Treating Digits or Spaces as Consonants
A subtle bug arises if you classify characters as consonants using a "not a vowel" rule without first confirming the character is a letter. For instance:
for ch in s: if ch in vowels: vowel_count += 1 else: consonant_count += 1 # WRONG: counts spaces and digits too!
This incorrectly counts spaces and digits as consonants, inflating consonant_count and producing a wrong score.
Solution: Always verify the character is alphabetic first using ch.isalpha() before deciding vowel vs. consonant. This guarantees spaces and digits are skipped entirely.
Pitfall 3: Using Float Division Instead of Integer Division
Some implementations write v / c (float division) and then call int(...) or math.floor(...). While math.floor works, using plain int() can be misleading if negatives were ever involved, and float division introduces unnecessary precision concerns.
return int(vowel_count / consonant_count) # avoid: float arithmetic
Solution: Use Python's integer floor-division operator //, which directly yields the floored result without any floating-point intermediate:
return vowel_count // consonant_count
Since both counts are non-negative integers, // exactly matches the required floor(v / c) semantics.
Pitfall 4: Case Sensitivity Assumptions
Although this problem guarantees only lowercase letters, reusing this logic on mixed-case input would misclassify uppercase vowels like 'A' or 'E' as consonants because the vowel set only contains lowercase letters.
Solution: If the constraints ever change to allow uppercase, normalize with ch.lower() before the membership check:
if ch.lower() in vowels: vowel_count += 1
Ready to land your dream job?
Unlock your dream job with a 5-minute quiz for a personalized study roadmap!
Get My RoadmapWhat's the output of running the following function using input [30, 20, 10, 100, 33, 12]?
1def fun(arr: List[int]) -> List[int]:
2 import heapq
3 heapq.heapify(arr)
4 res = []
5 for i in range(3):
6 res.append(heapq.heappop(arr))
7 return res
81public static int[] fun(int[] arr) {
2 int[] res = new int[3];
3 PriorityQueue<Integer> heap = new PriorityQueue<>();
4 for (int i = 0; i < arr.length; i++) {
5 heap.add(arr[i]);
6 }
7 for (int i = 0; i < 3; i++) {
8 res[i] = heap.poll();
9 }
10 return res;
11}
121class HeapItem {
2 constructor(item, priority = item) {
3 this.item = item;
4 this.priority = priority;
5 }
6}
7
8class MinHeap {
9 constructor() {
10 this.heap = [];
11 }
12
13 push(node) {
14 // insert the new node at the end of the heap array
15 this.heap.push(node);
16 // find the correct position for the new node
17 this.bubble_up();
18 }
19
20 bubble_up() {
21 let index = this.heap.length - 1;
22
23 while (index > 0) {
24 const element = this.heap[index];
25 const parentIndex = Math.floor((index - 1) / 2);
26 const parent = this.heap[parentIndex];
27
28 if (parent.priority <= element.priority) break;
29 // if the parent is bigger than the child then swap the parent and child
30 this.heap[index] = parent;
31 this.heap[parentIndex] = element;
32 index = parentIndex;
33 }
34 }
35
36 pop() {
37 const min = this.heap[0];
38 this.heap[0] = this.heap[this.size() - 1];
39 this.heap.pop();
40 this.bubble_down();
41 return min;
42 }
43
44 bubble_down() {
45 let index = 0;
46 let min = index;
47 const n = this.heap.length;
48
49 while (index < n) {
50 const left = 2 * index + 1;
51 const right = left + 1;
52
53 if (left < n && this.heap[left].priority < this.heap[min].priority) {
54 min = left;
55 }
56 if (right < n && this.heap[right].priority < this.heap[min].priority) {
57 min = right;
58 }
59 if (min === index) break;
60 [this.heap[min], this.heap[index]] = [this.heap[index], this.heap[min]];
61 index = min;
62 }
63 }
64
65 peek() {
66 return this.heap[0];
67 }
68
69 size() {
70 return this.heap.length;
71 }
72}
73
74function fun(arr) {
75 const heap = new MinHeap();
76 for (const x of arr) {
77 heap.push(new HeapItem(x));
78 }
79 const res = [];
80 for (let i = 0; i < 3; i++) {
81 res.push(heap.pop().item);
82 }
83 return res;
84}
85Recommended Readings
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion If you prefer videos here's a video that explains recursion in a fun and easy way Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask him
Runtime Overview When learning about algorithms and data structures you'll frequently encounter the term time complexity This concept is fundamental in computer science and offers insights into how long an algorithm takes to complete given a certain input size What is Time Complexity Time complexity describes how the time needed
Want a Structured Path to Master System Design Too? Don’t Miss This!