Reverse Only the Vowels of a String

Solve this Problem
Easy15–20 min
Topics
Companies
Practice:GFG ↗
Given a string s, reverse only the vowels in it and return the result — every consonant stays exactly where it is. Collecting every vowel into a separate list and handing them back out in reverse order works, but it costs an extra list the size of the vowel count. The two-pointerTwo PointerUsing two indices that move through one or more sequences to avoid redundant re-scanning. technique swaps vowels directly in place: walk pointers inward from both ends, sliding each one forward or backward until it lands on a vowel, then swap the pair and keep going. No extra storage is needed — the vowels trade positions as the pointers move toward the middle.

Test Case 1:

Input:s = "hello"
Output:"holle"
Explanation:The vowels 'e' and 'o' swap places; the consonants stay put.

Test Case 2:

Input:s = "leetcode"
Output:"leotcede"
Explanation:The vowels e, e, o, e are reversed in place to e, o, e, e.

Test Case 3:

Input:s = "aA"
Output:"Aa"
Explanation:Vowel matching is case-sensitive, but both 'a' and 'A' count as vowels.

Constraints

  • 1 ≤ s.length ≤ 3 × 10⁵
  • s consists of printable ASCII characters
🚀

Try the Dry Run

Don't just read the solution — watch it execute, one step at a time.

🧪Try your own test case
1class Solution {
2 public String reverseOnlyVowels(String s) {
3 char[] chars = s.toCharArray();
4 int left = 0, right = chars.length - 1;
5 while (left < right) {
6 while (left < right && !isVowel(chars[left])) left++;
7 while (left < right && !isVowel(chars[right])) right--;
8 if (left < right) {
9 char temp = chars[left];
10 chars[left] = chars[right];
11 chars[right] = temp;
12 left++;
13 right--;
14 }
15 }
16 return new String(chars);
17 }
18 private boolean isVowel(char c) {
19 return "aeiouAEIOU".indexOf(c) != -1;
20 }
21}
22
h
e
l
l
o
left
right
Variables
left0
right4
INITIALIZE

Set left to 0 and right to the last index, 4.

Step 1 / 5

Approach & Solutions

Brute Force — Collect, Then Rebuild

Brute

Walk the string once to collect every vowel into a separate list, in the order they appear. Then walk the string a second time, and for every position that holds a vowel, pull the next one off the *end* of that collected list (which puts them back in reverse order); every consonant is copied through unchanged. Correct, but it needs an extra list the size of the vowel count just to remember them.

TimeO(n)
SpaceO(n)
1class Solution { 2 public String reverseOnlyVowels(String s) { 3 Deque<Character> vowels = new ArrayDeque<>(); 4 for (char c : s.toCharArray()) { 5 if (isVowel(c)) vowels.addLast(c); 6 } 7 StringBuilder result = new StringBuilder(); 8 for (char c : s.toCharArray()) { 9 if (isVowel(c)) result.append(vowels.pollLast()); 10 else result.append(c); 11 } 12 return result.toString(); 13 } 14 private boolean isVowel(char c) { 15 return "aeiouAEIOU".indexOf(c) != -1; 16 } 17}

Optimal — Two Pointers, In Place

Optimal

Skip the second list entirely. Walk two pointers inward from both ends of the string. At each step, slide the left pointer forward until it lands on a vowel, and slide the right pointer backward until it lands on a vowel, then swap the two characters directly. No extra list is needed — the vowels swap into place as the pointers meet in the middle.

TimeO(n)
SpaceO(1) extra
1class Solution { 2 public String reverseOnlyVowels(String s) { 3 char[] chars = s.toCharArray(); 4 int left = 0, right = chars.length - 1; 5 while (left < right) { 6 while (left < right && !isVowel(chars[left])) left++; 7 while (left < right && !isVowel(chars[right])) right--; 8 if (left < right) { 9 char temp = chars[left]; 10 chars[left] = chars[right]; 11 chars[right] = temp; 12 left++; 13 right--; 14 } 15 } 16 return new String(chars); 17 } 18 private boolean isVowel(char c) { 19 return "aeiouAEIOU".indexOf(c) != -1; 20 } 21}

Related Problems