Facebook Pixel

3775. Reverse Words With Same Vowel Count

MediumTwo PointersStringSimulation
LeetCode ↗

Problem Description

You are given a string s made up of lowercase English words, where each word is separated by a single space.

Your task involves these steps:

  1. Count the vowels in the first word. Vowels are the characters 'a', 'e', 'i', 'o', and 'u'. Let this count be the reference value.

  2. Process every word after the first one. For each of these following words, count how many vowels it contains:

    • If a word has the same number of vowels as the first word, reverse that word.
    • Otherwise, leave the word unchanged.
  3. The first word itself stays the same (it is never reversed).

  4. After processing all words, join them back together with single spaces and return the resulting string.

For example, if the first word has 2 vowels, then any later word that also has exactly 2 vowels gets reversed, while words with a different vowel count are kept as they are.

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

How We Pick the Algorithm

Why Simulation / Basic DSA?

This problem maps to Simulation / Basic DSA through a short path in the full flowchart.

JustsimulatetheyesTwopointersor slidingnoSimulation /Basic DSA

Counting vowels and conditionally reversing words is a direct simulation of the described process.

Open in Flowchart

Intuition

The problem describes a clear sequence of actions, so we can solve it by directly simulating exactly what is asked.

The key observation is that everything depends on a single number: the vowel count of the first word. Once we know this reference count, every other word can be handled independently—we just compare its own vowel count against the reference.

To make counting vowels easy, we can write a small helper that, for a given word, checks each character to see if it belongs to the set "aeiou" and adds up the matches. This gives us the number of vowels in any word.

With this helper in hand, the rest follows naturally:

  • Split the string into a list of words so we can work with each one separately.
  • Compute the reference count cnt from the first word.
  • Walk through the remaining words one by one. For each word, if its vowel count equals cnt, we reverse it (using slicing w[::-1]); otherwise we keep it as is.
  • Finally, join all the words back with spaces to form the answer.

Since each word's fate only relies on comparing its vowel count to a fixed value, a single pass through the words is enough to build the result.

Pattern Learn more about Two Pointers patterns.

Solution Approach

Solution 1: Simulation

We solve the problem by directly simulating the described steps.

Step 1: Define a vowel-counting helper.

We create a helper function calc(w) that takes a word w and returns its number of vowels. For each character c in the word, the expression c in "aeiou" evaluates to True (counted as 1) when c is a vowel and False (counted as 0) otherwise. Summing these boolean values with sum(...) gives the total vowel count of the word.

Step 2: Split the string into words.

We use s.split() to break the input string into a list words, where each element is a single word.

Step 3: Get the reference count.

We compute cnt = calc(words[0]), the number of vowels in the first word. The first word is added to our answer list ans unchanged, since it is never reversed.

Step 4: Process the remaining words.

We iterate through words[1:]. For each word w:

  • If calc(w) == cnt, the word has the same vowel count as the first word, so we reverse it using slicing w[::-1] and append it to ans.
  • Otherwise, we append the word w as is.

Step 5: Build the result.

After processing all words, we join the list ans back into a single string with " ".join(ans) and return it.

The time complexity is O(n), where n is the length of the string s, since we scan every character once to count vowels and once more during reversal and joining. The space complexity is O(n), used for storing the list of words and the final result.

Example Walkthrough

Let's trace through the solution approach using a small example:

Input: s = "hello world apple sky"


Step 1: Define the vowel-counting helper.

The helper calc(w) counts vowels in a word. For example:

  • calc("hello")'e' and 'o' are vowels → 2
  • calc("world") → only 'o' is a vowel → 1
  • calc("apple")'a' and 'e' are vowels → 2
  • calc("sky") → no vowels → 0

Step 2: Split the string into words.

words = ["hello", "world", "apple", "sky"]

Step 3: Get the reference count.

The first word is "hello", so:

cnt = calc("hello") = 2
ans = ["hello"]   # first word stays unchanged

Our reference value is 2 vowels.


Step 4: Process the remaining words ["world", "apple", "sky"].

WordVowel CountEquals cnt (2)?ActionResult
world1NoKeep as isworld
apple2YesReverse → elppaelppa
sky0NoKeep as issky

After processing:

ans = ["hello", "world", "elppa", "sky"]
  • "world" has 1 vowel ≠ 2 → left unchanged.
  • "apple" has 2 vowels = 2 → reversed to "elppa".
  • "sky" has 0 vowels ≠ 2 → left unchanged.

Step 5: Build the result.

Join the list with spaces:

" ".join(["hello", "world", "elppa", "sky"]) = "hello world elppa sky"

Output: "hello world elppa sky"

This walkthrough shows how the reference count (2 from "hello") drives every decision: only words matching that exact vowel count get reversed, while all others remain untouched.

Solution Implementation

1class Solution:
2    def reverseWords(self, s: str) -> str:
3        # Count the number of vowels in a given word
4        def count_vowels(word: str) -> int:
5            return sum(char in "aeiou" for char in word)
6
7        # Split the input string into individual words
8        words = s.split()
9
10        # Use the vowel count of the first word as the reference count
11        reference_count = count_vowels(words[0])
12
13        # The first word is always kept as-is in the result
14        result = [words[0]]
15
16        # Process every subsequent word
17        for word in words[1:]:
18            # If the word has the same vowel count as the reference,
19            # reverse it; otherwise keep it unchanged
20            if count_vowels(word) == reference_count:
21                result.append(word[::-1])
22            else:
23                result.append(word)
24
25        # Join the processed words back into a single string
26        return " ".join(result)
27
1class Solution {
2    /**
3     * Reverses every word whose vowel count matches the vowel count of the first word.
4     *
5     * @param s the input sentence (words separated by whitespace)
6     * @return the resulting sentence after conditional reversal
7     */
8    public String reverseWords(String s) {
9        // Split the input on one or more whitespace characters.
10        String[] words = s.split("\\s+");
11
12        // Use the first word's vowel count as the reference value.
13        int referenceVowelCount = calc(words[0]);
14
15        // Collect the processed words here.
16        List<String> result = new ArrayList<>();
17
18        // The first word is always added as-is (it is its own reference).
19        result.add(words[0]);
20
21        // Process the remaining words one by one.
22        for (int i = 1; i < words.length; i++) {
23            String word = words[i];
24
25            // If this word has the same number of vowels as the reference,
26            // reverse it; otherwise keep it unchanged.
27            if (calc(word) == referenceVowelCount) {
28                result.add(new StringBuilder(word).reverse().toString());
29            } else {
30                result.add(word);
31            }
32        }
33
34        // Re-join the words into a single space-separated sentence.
35        return String.join(" ", result);
36    }
37
38    /**
39     * Counts the number of lowercase vowels (a, e, i, o, u) in the given word.
40     *
41     * @param word the word to inspect
42     * @return the number of vowels found
43     */
44    private int calc(String word) {
45        int count = 0;
46        for (char c : word.toCharArray()) {
47            // Increment the counter whenever the character is a vowel.
48            if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') {
49                count++;
50            }
51        }
52        return count;
53    }
54}
55
1class Solution {
2public:
3    string reverseWords(string s) {
4        // Use a stream to split the input into words by whitespace.
5        stringstream ss(s);
6        string word;
7
8        // Read the first word; its vowel count is the reference value.
9        ss >> word;
10        int referenceVowelCount = countVowels(word);
11
12        // The first word is appended as-is (it defines the reference count).
13        string ans = word;
14
15        // Process every remaining word.
16        while (ss >> word) {
17            // Separate words with a single space.
18            ans.push_back(' ');
19
20            // If this word has the same number of vowels as the first word,
21            // reverse its characters before appending.
22            if (countVowels(word) == referenceVowelCount) {
23                reverse(word.begin(), word.end());
24            }
25
26            ans += word;
27        }
28
29        return ans;
30    }
31
32private:
33    // Count the number of vowels (a, e, i, o, u) in the given word.
34    int countVowels(const string& word) {
35        return count_if(word.begin(), word.end(), [](char c) {
36            return c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u';
37        });
38    }
39};
40
1function reverseWords(s: string): string {
2    // Split the input string into words, using one or more whitespace characters as the delimiter
3    const words: string[] = s.split(/\s+/);
4
5    // Helper function: count the number of vowels (a, e, i, o, u) in a given word
6    const countVowels = (word: string): number => {
7        let count = 0;
8        for (const ch of word) {
9            if ('aeiou'.includes(ch)) {
10                count++;
11            }
12        }
13        return count;
14    };
15
16    // Use the vowel count of the first word as the reference value
17    const referenceCount: number = countVowels(words[0]);
18
19    // The result array starts with the first word unchanged
20    const result: string[] = [words[0]];
21
22    // Iterate over the remaining words starting from the second one
23    for (let i = 1; i < words.length; i++) {
24        let word: string = words[i];
25
26        // If the current word has the same vowel count as the reference, reverse it
27        if (countVowels(word) === referenceCount) {
28            word = word.split('').reverse().join('');
29        }
30
31        // Append the (possibly reversed) word to the result
32        result.push(word);
33    }
34
35    // Join all words back into a single string separated by spaces
36    return result.join(' ');
37}
38

Time and Space Complexity

  • Time Complexity: O(n), where n is the length of the string s. Splitting the string with s.split() takes O(n). The calc function iterates over the characters of a word, and across all words the total number of characters processed is O(n). Reversing words with w[::-1] and joining the result with " ".join(ans) also take O(n) in total. Therefore, the overall time complexity is O(n).

  • Space Complexity: O(n), where n is the length of the string s. The words list and the ans list together store all the characters of the string, requiring O(n) space. The final joined string also occupies O(n) space. Hence, the overall space complexity is O(n).

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

Common Pitfalls

Pitfall 1: Crashing on an Empty Input String

The most common pitfall is assuming the input always contains at least one word. The code directly accesses words[0] and computes reference_count = count_vowels(words[0]). If s is an empty string "" (or a string consisting only of spaces), then s.split() returns an empty list []. Accessing words[0] on an empty list immediately raises an IndexError, crashing the program.

Solution: Guard against an empty words list before accessing the first element.

class Solution:
    def reverseWords(self, s: str) -> str:
        def count_vowels(word: str) -> int:
            return sum(char in "aeiou" for char in word)

        words = s.split()

        # Defensive check: return early if there are no words
        if not words:
            return ""

        reference_count = count_vowels(words[0])
        result = [words[0]]

        for word in words[1:]:
            if count_vowels(word) == reference_count:
                result.append(word[::-1])
            else:
                result.append(word)

        return " ".join(result)

Pitfall 2: Losing the Original Spacing

The code uses s.split() followed by " ".join(result). This works perfectly when words are separated by a single space, as the problem guarantees. However, if the input were ever to contain multiple spaces, leading/trailing spaces, or tabs, split() would collapse them all, and the rejoined result would not preserve the original whitespace.

Solution: Since the problem explicitly states single-space separation, the current approach is correct. But if arbitrary whitespace had to be preserved, you would need to split on the literal separator (e.g., s.split(" ")) instead of the default split(), which treats runs of whitespace as one delimiter:

# Preserves exact single-space structure, including empty tokens
words = s.split(" ")

Be aware that s.split(" ") produces empty strings for consecutive spaces, so count_vowels("") returning 0 must be handled intentionally in that scenario.

Pitfall 3: Reversing the First Word by Accident

A subtle logic error is iterating over all words (including the first one) when checking the vowel count. Since the first word's vowel count always equals the reference count (it is the reference), a naive loop over words instead of words[1:] would reverse the first word too, violating rule 3.

Solution: Always start the comparison loop from the second word using words[1:], and seed the result list with the unmodified first word — exactly as the provided code does. This cleanly separates the reference word from the words being processed.

Ready to land your dream job?

Unlock your dream job with a 5-minute quiz for a personalized study roadmap!

Get My Roadmap
Discover Your Strengths and Weaknesses: Take Our 5-Minute Quiz to Get a Personalized Study Roadmap:

Depth first search is equivalent to which of the tree traversal order?


Recommended Readings

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

Load More