Python 0345.py
class Solution:
def reverseVowels(self, s: str) -> str:
vowels = { "a", "e", "i", "o", "u", "A", "E", "I", "O", "U" }
v = []
for c in s:
if c in vowels:
v.append(c)
result = ""
for c in s:
if c in vowels:
result = result + v.pop()
else:
result = result + c
return result
Difficulty
and has an acceptance rate of about 62% (2+ million submissions).
Typical patterns to solve this problem:
- String
- Two Pointers
AI Disclaimer
However, two years later I set up this website and used various AI tools to generate most of the walkthrough / explanations below.
See this dedicated page for more details.
Code Walkthrough
Overview
The provided Solution class implements a method reverseVowels that receives a string s and returns a new string where the vowels in s appear in reverse order while all non-vowel characters retain their original positions. The algorithm proceeds in two linear passes: the first extracts all vowels, the second rebuilds the output by substituting each vowel with the next one from the reversed collection.
Key Steps
Collecting Vowels
The method begins by defining a set containing both lowercase and uppercase vowel characters. Using a set enables constant-time membership checks. It then iterates over each character in the input string, appending any character that belongs to the vowel set to a list v. This list preserves the order of appearance of vowels, which will later be reversed by popping from the end.
vowels = { "a", "e", "i", "o", "u", "A", "E", "I", "O", "U" }
v = []
for c in s:
if c in vowels:
v.append(c)
Reconstructing Result
After gathering all vowels, the method constructs the final string. It initializes an empty string result and walks through the original string again. For each character, it checks whether the character is a vowel. If it is, the method appends the last element of v (obtained via pop()) to result, thereby inserting vowels in reverse order. If the character is not a vowel, it is appended unchanged.
result = ""
for c in s:
if c in vowels:
result = result + v.pop()
else:
result = result + c
return result
Edge Cases Handled
The algorithm gracefully handles an empty input string because the initial loops simply do not execute and the method returns an empty string. When the input contains no vowels, the list v remains empty; the second loop never attempts to pop from it because the vowel check fails for every character, resulting in the original string being returned unchanged. Strings composed exclusively of vowels are also correctly processed: the first loop collects all characters, and the second loop replaces each with the next vowel from the end of the list, effectively reversing the entire string. Mixed-case vowels are treated uniformly because the vowel set includes both cases, ensuring that uppercase vowels are recognized and reversed alongside lowercase ones. Consecutive vowel sequences are reversed as a block, preserving the relative order of surrounding consonants.
Performance Optimizations
A notable optimization is the use of a hash set for vowel membership testing. Set lookups execute in constant time, which is faster than scanning a list or string for each character. The collection of vowels into a list serves as a stack; using pop() removes the last element in constant time, providing an efficient way to retrieve vowels in reverse order without additional indexing arithmetic. By separating the extraction and reconstruction phases, the method avoids repeated scanning of the input for both vowel identification and placement, ensuring that each character is examined only twice. The algorithm also avoids auxiliary data structures beyond the minimal list for vowels and the result string, keeping memory usage tight while still achieving the desired reversal behavior.
ELI5 - Simplified Explanation
Imagine that every word or phrase is like a little train made of letters. Some of those letters are special, and they are called vowels. This code looks at all the letters in a string and picks out just those special vowels to put into a private box. After gathering all the vowels in the box, the code looks at the original string again from the very beginning. When it finds a regular letter that is not a vowel, it keeps the letter exactly where it is. When it finds one of the special vowels, it takes the very last vowel out of the box and uses that instead. Since the box gives back the vowels in reverse order, the vowels at the end of the line end up swapping places with the vowels at the start. Eventually, all the vowels end up in different spots than where they started, creating a new string where the vowels are backwards.
Code Quality
Complexity Analysis
Other Solutions
Obviously, I did that after I solved the problem myself.
In general, AlgoMonster and WalkCCC solutions are high-quality and always worth a look.
I haven't checked most of the other solutions, but they might be helpful as well.
And of course, the LeetCode forum is always a good place (or even the best) to look for alternative approaches.
(click on a column header to sort the table)
| author | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| author | solutions | ||||||||||
| www | AlgoMonster | C++ | Python | Java | TS | ||||||
| WalkCCC | C++ | Python | Java | ||||||||
| leetcode.ca | C++ | Python | Java | Rust | Go | TS | |||||
| LeetcodeHelp | C++ | Python | Java | ||||||||
| MemoryLimitExceeded | C++ | Python | |||||||||
| Progiez | C++ | Python | Java | ||||||||
| github | BigEggStudy | C# | |||||||||
| black-shadows | C++ | ||||||||||
| charles-wangkai | Java | ||||||||||
| DimitrisJim | C | ||||||||||
| everthis | JS | ||||||||||
| fartem | Ruby | ||||||||||
| halfrost | Go | ||||||||||
| haoel | C++ | ||||||||||
| JoshCrozier | JS | ||||||||||
| keineahnung2345 | C++ | ||||||||||
| Krazune | C++ | ||||||||||
| linouk23 | C++ | ||||||||||
| lkwq007 | Python | ||||||||||
| lzl124631x | C++ | ||||||||||
| qiyuangong | Python | ||||||||||
| ruoru | Rust | ||||||||||
| shreymehul | C# | ||||||||||
| suxrobGM | C# | ||||||||||
| varunu28 | Java | ||||||||||
| vli02 | C | ||||||||||
| vthwang | Java | ||||||||||
| XiaotaoGuo | C++ | ||||||||||
| YuriSpiridonov | Python | ||||||||||
| zfang399 | C++ | ||||||||||
| AlgoMonster | C++, Python, Java, TypeScript | ||||||||||
| WalkCCC | C++, Python, Java | ||||||||||
| leetcode.ca | C++, Go, Java, Python, Rust, TypeScript | ||||||||||
| LeetcodeHelp | C++, Java, Python | ||||||||||
| MemoryLimitExceeded | Python, C++ | ||||||||||
| Progiez | C++, Java, Python | ||||||||||
| BigEggStudy | C# | ||||||||||
| black-shadows | C++, C++ | ||||||||||
| charles-wangkai | Java | ||||||||||
| DimitrisJim | C | ||||||||||
| everthis | JavaScript | ||||||||||
| fartem | Ruby | ||||||||||
| halfrost | Go | ||||||||||
| haoel | C++ | ||||||||||
| JoshCrozier | JavaScript | ||||||||||
| keineahnung2345 | C++ | ||||||||||
| Krazune | C++ | ||||||||||
| linouk23 | C++ | ||||||||||
| lkwq007 | Python | ||||||||||
| lzl124631x | C++ | ||||||||||
| qiyuangong | Python | ||||||||||
| ruoru | Rust | ||||||||||
| shreymehul | C# | ||||||||||
| suxrobGM | C# | ||||||||||
| varunu28 | Java | ||||||||||
| vli02 | C | ||||||||||
| vthwang | Java | ||||||||||
| XiaotaoGuo | C++ | ||||||||||
| YuriSpiridonov | Python | ||||||||||
| zfang399 | C++ |
Videos
Similar Problems
- problem 344: Reverse String
- problem 2785: Sort Vowels in a String
Solved On The Same Day
- problem 342: Power of Four
- problem 344: Reverse String
- problem 349: Intersection of Two Arrays
- problem 350: Intersection of Two Arrays II
- problem 387: First Unique Character in a String
- problem 412: Fizz Buzz
- problem 414: Third Maximum Number
- problem 434: Number of Segments in a String
- problem 448: Find All Numbers Disappeared in an Array
- problem 485: Max Consecutive Ones
- problem 504: Base 7
- problem 507: Perfect Number
Extra
- Tech Stack - my development environment and tools
- AI - how AI helped me create this website (NOT solving the problems)
- Progress - progression over time
- Quality - code quality