Given a string s
, reverse only all the vowels in the string and return it.
The vowels are 'a'
, 'e'
, 'i'
, 'o'
, and 'u'
, and they can appear in both lower and upper cases, more than once.
Example 1:
Input: s = "IceCreAm"
Output: "AceCreIm"
Explanation:
The vowels in s
are ['I', 'e', 'e', 'A']
. On reversing the vowels, s becomes "AceCreIm"
.
Example 2:
Input: s = "leetcode"
Output: "leotcede"
Constraints:
1 <= s.length <= 3 * 105
s
consist of printable ASCII characters.This problem asks us to reverse only the vowels in a given string. The approach uses two pointers, one starting from the beginning and the other from the end of the string. The pointers move towards each other, swapping vowels when they are encountered.
Initialization:
vowels
containing all lowercase and uppercase vowels ('a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'). This allows for efficient vowel checking.left
and right
, to the beginning and end of the string, respectively.Iteration:
left
is less than right
:
left
pointer: While left
points to a non-vowel character, increment left
.right
pointer: While right
points to a non-vowel character, decrement right
.left
is still less than right
(meaning both pointers now point to vowels), swap the characters at left
and right
. Then, increment left
and decrement right
.Return:
Python:
def reverseVowels(s: str) -> str:
vowels = "aeiouAEIOU"
left, right = 0, len(s) - 1
s_list = list(s) # Convert string to list for mutability
while left < right:
while left < right and s_list[left] not in vowels:
left += 1
while left < right and s_list[right] not in vowels:
right -= 1
if left < right:
s_list[left], s_list[right] = s_list[right], s_list[left]
left += 1
right -= 1
return "".join(s_list) # Convert back to string
Java:
class Solution {
public String reverseVowels(String s) {
Set<Character> vowels = new HashSet<>(Arrays.asList('a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'));
char[] chars = s.toCharArray();
int left = 0, right = chars.length - 1;
while (left < right) {
while (left < right && !vowels.contains(chars[left])) {
left++;
}
while (left < right && !vowels.contains(chars[right])) {
right--;
}
if (left < right) {
char temp = chars[left];
chars[left] = chars[right];
chars[right] = temp;
left++;
right--;
}
}
return new String(chars);
}
}
C++:
string reverseVowels(string s) {
unordered_set<char> vowels = {'a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'};
int left = 0, right = s.length() - 1;
while (left < right) {
while (left < right && vowels.find(s[left]) == vowels.end()) {
left++;
}
while (left < right && vowels.find(s[right]) == vowels.end()) {
right--;
}
if (left < right) {
swap(s[left], s[right]);
left++;
right--;
}
}
return s;
}
The other languages (Go, TypeScript, Rust) follow a very similar structure. The key elements are: the vowel set for efficient lookup, the two-pointer approach for traversal, and in-place swapping of vowels. Minor syntax differences exist between languages, but the core algorithm remains the same.