Facebook Pixel

3541. Find Most Frequent Vowel and Consonant

EasyHash TableStringCounting
Leetcode Link

Problem Description

You are given a string s that contains only lowercase English letters from 'a' to 'z'.

Your task is to find two specific letters in the string:

  1. The vowel ('a', 'e', 'i', 'o', or 'u') that appears most frequently in the string
  2. The consonant (any letter that is not a vowel) that appears most frequently in the string

Once you find these two letters, return the sum of their frequencies (how many times each appears in the string).

Important points to note:

  • The frequency of a letter is the number of times it appears in the string
  • If multiple vowels have the same maximum frequency, you can pick any of them
  • If multiple consonants have the same maximum frequency, you can pick any of them
  • If the string contains no vowels, treat the vowel frequency as 0
  • If the string contains no consonants, treat the consonant frequency as 0

For example, if the most frequent vowel appears 5 times and the most frequent consonant appears 3 times, you would return 5 + 3 = 8.

Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

Intuition

The problem asks us to find the maximum frequencies of vowels and consonants separately, then add them together. This naturally leads us to think about counting each character's frequency first.

Since we need to distinguish between vowels and consonants, we can process each character and categorize it accordingly. The key insight is that we don't need to track which specific vowel or consonant has the maximum frequency - we only care about the maximum frequency values themselves.

We can maintain two variables: one for tracking the maximum frequency among vowels (a) and another for tracking the maximum frequency among consonants (b). As we iterate through our frequency count, we check if each character is a vowel (by checking if it's in "aeiou"). If it is, we update our vowel maximum; otherwise, we update our consonant maximum.

This approach is efficient because we only need to:

  1. Count all character frequencies once using a Counter or hash table
  2. Make a single pass through the frequency data to find both maximums
  3. Simply return the sum of these two maximum values

The beauty of this solution is its simplicity - we don't need complex data structures or multiple passes through the string. We just count, categorize, and keep track of the maximums as we go.

Solution Approach

The solution uses a counting approach with the following steps:

  1. Count Character Frequencies: We use Python's Counter from the collections module to create a hash table cnt that stores the frequency of each character in the string s. This gives us a dictionary where keys are characters and values are their frequencies.

  2. Initialize Maximum Trackers: We initialize two variables:

    • a = 0: to track the maximum frequency among vowels
    • b = 0: to track the maximum frequency among consonants
  3. Iterate and Categorize: We iterate through the cnt dictionary using .items() to get each character c and its frequency v:

    • If the character c is a vowel (checked by c in "aeiou"), we update a to be the maximum of the current a and this vowel's frequency v
    • Otherwise, the character is a consonant, so we update b to be the maximum of the current b and this consonant's frequency v
  4. Return the Sum: After processing all characters, we return a + b, which represents the sum of the maximum vowel frequency and maximum consonant frequency.

The time complexity is O(n) where n is the length of the string (for counting) plus O(26) for iterating through at most 26 unique letters, which simplifies to O(n). The space complexity is O(1) since we store at most 26 character frequencies in the counter.

This approach handles edge cases naturally:

  • If there are no vowels, a remains 0
  • If there are no consonants, b remains 0
  • If multiple vowels or consonants share the maximum frequency, we automatically pick one during the max comparison

Ready to land your dream job?

Unlock your dream job with a 5-minute evaluator for a personalized learning plan!

Start Evaluator

Example Walkthrough

Let's walk through the solution with the string s = "aabbbccde".

Step 1: Count Character Frequencies Using Counter, we get:

  • 'a': 2 times
  • 'b': 3 times
  • 'c': 2 times
  • 'd': 1 time
  • 'e': 1 time

So cnt = {'a': 2, 'b': 3, 'c': 2, 'd': 1, 'e': 1}

Step 2: Initialize Maximum Trackers

  • a = 0 (for vowels)
  • b = 0 (for consonants)

Step 3: Iterate and Categorize Process each character and its frequency:

  1. 'a' with frequency 2:

    • 'a' is in "aeiou" → it's a vowel
    • Update a = max(0, 2) = 2
    • Current state: a = 2, b = 0
  2. 'b' with frequency 3:

    • 'b' is not in "aeiou" → it's a consonant
    • Update b = max(0, 3) = 3
    • Current state: a = 2, b = 3
  3. 'c' with frequency 2:

    • 'c' is not in "aeiou" → it's a consonant
    • Update b = max(3, 2) = 3 (no change)
    • Current state: a = 2, b = 3
  4. 'd' with frequency 1:

    • 'd' is not in "aeiou" → it's a consonant
    • Update b = max(3, 1) = 3 (no change)
    • Current state: a = 2, b = 3
  5. 'e' with frequency 1:

    • 'e' is in "aeiou" → it's a vowel
    • Update a = max(2, 1) = 2 (no change)
    • Final state: a = 2, b = 3

Step 4: Return the Sum Return a + b = 2 + 3 = 5

The most frequent vowel is 'a' with frequency 2, and the most frequent consonant is 'b' with frequency 3, giving us a total of 5.

Solution Implementation

1from collections import Counter
2
3class Solution:
4    def maxFreqSum(self, s: str) -> int:
5        # Count frequency of each character in the string
6        char_frequency = Counter(s)
7      
8        # Initialize maximum frequencies for vowels and consonants
9        max_vowel_freq = 0
10        max_consonant_freq = 0
11      
12        # Iterate through each character and its frequency
13        for char, freq in char_frequency.items():
14            # Check if character is a vowel
15            if char in "aeiou":
16                # Update maximum vowel frequency if current is larger
17                max_vowel_freq = max(max_vowel_freq, freq)
18            else:
19                # Update maximum consonant frequency if current is larger
20                max_consonant_freq = max(max_consonant_freq, freq)
21      
22        # Return sum of maximum vowel and consonant frequencies
23        return max_vowel_freq + max_consonant_freq
24
1class Solution {
2    public int maxFreqSum(String s) {
3        // Array to store frequency count of each letter (a-z)
4        int[] frequencyCount = new int[26];
5      
6        // Count the frequency of each character in the string
7        for (char character : s.toCharArray()) {
8            frequencyCount[character - 'a']++;
9        }
10      
11        // Variables to track maximum frequency among vowels and consonants
12        int maxVowelFrequency = 0;
13        int maxConsonantFrequency = 0;
14      
15        // Iterate through the frequency array to find max frequencies
16        for (int i = 0; i < frequencyCount.length; i++) {
17            char currentChar = (char) (i + 'a');
18          
19            // Check if current character is a vowel
20            if (currentChar == 'a' || currentChar == 'e' || currentChar == 'i' || 
21                currentChar == 'o' || currentChar == 'u') {
22                // Update maximum vowel frequency if current is greater
23                maxVowelFrequency = Math.max(maxVowelFrequency, frequencyCount[i]);
24            } else {
25                // Update maximum consonant frequency if current is greater
26                maxConsonantFrequency = Math.max(maxConsonantFrequency, frequencyCount[i]);
27            }
28        }
29      
30        // Return the sum of maximum vowel frequency and maximum consonant frequency
31        return maxVowelFrequency + maxConsonantFrequency;
32    }
33}
34
1class Solution {
2public:
3    int maxFreqSum(string s) {
4        // Array to store frequency count of each letter (a-z)
5        int frequency[26]{};
6      
7        // Count the frequency of each character in the string
8        for (char c : s) {
9            ++frequency[c - 'a'];
10        }
11      
12        // Variables to track maximum frequency of vowels and consonants
13        int maxVowelFreq = 0;
14        int maxConsonantFreq = 0;
15      
16        // Iterate through all 26 letters to find max frequencies
17        for (int i = 0; i < 26; ++i) {
18            char currentChar = 'a' + i;
19          
20            // Check if current character is a vowel
21            if (currentChar == 'a' || currentChar == 'e' || currentChar == 'i' || 
22                currentChar == 'o' || currentChar == 'u') {
23                // Update maximum vowel frequency if current is greater
24                maxVowelFreq = max(maxVowelFreq, frequency[i]);
25            } else {
26                // Update maximum consonant frequency if current is greater
27                maxConsonantFreq = max(maxConsonantFreq, frequency[i]);
28            }
29        }
30      
31        // Return sum of maximum vowel frequency and maximum consonant frequency
32        return maxVowelFreq + maxConsonantFreq;
33    }
34};
35
1/**
2 * Calculates the sum of maximum frequency of a vowel and maximum frequency of a consonant in a string
3 * @param s - The input string to analyze
4 * @returns The sum of the highest vowel frequency and highest consonant frequency
5 */
6function maxFreqSum(s: string): number {
7    // Initialize frequency array for 26 lowercase letters (a-z)
8    const charFrequency: number[] = Array(26).fill(0);
9  
10    // Count frequency of each character in the string
11    for (const char of s) {
12        // Convert character to index (0-25) by subtracting ASCII value of 'a' (97)
13        const index: number = char.charCodeAt(0) - 97;
14        charFrequency[index]++;
15    }
16  
17    // Variables to track maximum frequencies
18    let maxVowelFrequency: number = 0;
19    let maxConsonantFrequency: number = 0;
20  
21    // Find maximum frequency among vowels and consonants
22    for (let i = 0; i < 26; i++) {
23        // Convert index back to character for vowel checking
24        const currentChar: string = String.fromCharCode(i + 97);
25      
26        if ('aeiou'.includes(currentChar)) {
27            // Update maximum vowel frequency if current is higher
28            maxVowelFrequency = Math.max(maxVowelFrequency, charFrequency[i]);
29        } else {
30            // Update maximum consonant frequency if current is higher
31            maxConsonantFrequency = Math.max(maxConsonantFrequency, charFrequency[i]);
32        }
33    }
34  
35    // Return the sum of maximum vowel and consonant frequencies
36    return maxVowelFrequency + maxConsonantFrequency;
37}
38

Time and Space Complexity

The time complexity is O(n), where n is the length of the string s. This is because the Counter(s) operation needs to iterate through each character in the string once to count the frequency of each character. The subsequent iteration through the counter dictionary takes O(|Σ|) time where |Σ| is the size of the alphabet (at most 26 for lowercase English letters), but since |Σ| is constant and much smaller than n in general cases, the overall time complexity remains O(n).

The space complexity is O(|Σ|), where |Σ| is the size of the alphabet. The Counter object stores at most one entry for each unique character in the string, which is bounded by the size of the alphabet (26 for lowercase English letters). Therefore, the space required is constant with respect to the input size and depends only on the alphabet size.

Learn more about how to find time and space complexity quickly.

Common Pitfalls

1. Incorrectly Identifying Vowels

A common mistake is using the wrong set of vowels or forgetting case sensitivity. Some developers might accidentally include 'y' as a vowel or use uppercase vowels when the problem specifically states lowercase letters only.

Incorrect:

if char in "aeiouy":  # 'y' is not a vowel in this problem
    max_vowel_freq = max(max_vowel_freq, freq)

# or
if char in "AEIOUaeiou":  # Problem states only lowercase
    max_vowel_freq = max(max_vowel_freq, freq)

Correct:

if char in "aeiou":  # Only lowercase vowels as specified
    max_vowel_freq = max(max_vowel_freq, freq)

2. Returning Wrong Values When No Vowels or Consonants Exist

Some might try to handle edge cases explicitly but end up overcomplicating or returning incorrect values when the string contains only vowels or only consonants.

Incorrect:

if max_vowel_freq == 0 and max_consonant_freq == 0:
    return -1  # Wrong: should return 0
  
# or returning None/raising exception for edge cases

Correct: The original solution handles this naturally by initializing both frequencies to 0 and only updating them when found.

3. Finding Sum of ALL Vowel and Consonant Frequencies

A misreading of the problem might lead to summing all vowel frequencies and all consonant frequencies instead of just the maximum ones.

Incorrect:

total_vowel_freq = 0
total_consonant_freq = 0

for char, freq in char_frequency.items():
    if char in "aeiou":
        total_vowel_freq += freq  # Summing all vowels
    else:
        total_consonant_freq += freq  # Summing all consonants
      
return total_vowel_freq + total_consonant_freq

Correct: Track only the maximum frequency for each category as shown in the original solution.

4. Manual Character Counting Instead of Using Counter

While not incorrect, manually counting characters is more error-prone and less efficient to write.

Less Optimal:

char_frequency = {}
for char in s:
    if char in char_frequency:
        char_frequency[char] += 1
    else:
        char_frequency[char] = 1

Better:

char_frequency = Counter(s)  # Cleaner and less error-prone
Discover Your Strengths and Weaknesses: Take Our 5-Minute Quiz to Tailor Your Study Plan:

Which technique can we use to find the middle of a linked list?


Recommended Readings

Want a Structured Path to Master System Design Too? Don’t Miss This!

Load More