Browse curriculum

Reverse Vowels of a String

Reverse the order of the vowels in a string while every consonant stays in place, using two pointers that skip consonants and swap vowels.

Problem Understanding

Reverse Vowels of a String (LeetCode 345): given a string s, reverse only its vowels and return the result. The vowels are a, e, i, o and u, in lower and upper case; every other character keeps its position.

Examples: "IceCreAm" → "AceCreIm"; "leetcode" → "leotcede".

The Intuition: Reverse a String, but Skip the Consonants

Reversing a whole string swaps the outermost pair and works inward. Here, do the same, but treat consonants as if they were not there.

  1. Two pointers at the two ends.
  2. Skip any consonant on either side.
  3. Swap when both pointers are on vowels, then move both inward.

It is Valid Palindrome's skip-what-does-not-count loop, with a swap where that lesson compares.

Interactive Walkthrough

CONSONANTS NEVER MOVE

l = 0, r = n − 1

s (vowels tinted)

l

I

0

c

1

e

2

C

3

r

4

e

5

A

6

r

m

7

l

0

r

7

Swaps

0

 

l starts at index 0 and r at index 7

Next

'm' at 7 is not a vowel: move r left to 6

Free preview: the first 3 of 7 steps

s

Vowels are tinted so you can see where l and r will stop. Consonants never move. Swapped vowels turn green. Try Case to see upper and lower case treated alike.

Dry Run Table

Input: s = "IceCreAm".

l r Action String
0 (I) 7 (m) r is a consonant: r = 6 IceCreAm
0 (I) 6 (A) swap AceCreIm
1 (c) 5 (e) l is a consonant: l = 2 AceCreIm
2 (e) 5 (e) swap AceCreIm
3 (C) 4 (r) l is a consonant: l = 4, pointers meet AceCreIm

Answer: "AceCreIm".

The Solution Template

Two pointers over a character array; a vowel set makes each check O(1).

Reverse Vowels of a String Code
1var reverseVowels = function(s) {
2 const vowels = new Set('aeiouAEIOU');
3 const chars = [...s];
4 let l = 0, r = chars.length - 1;
5 while (l < r) {
6 if (!vowels.has(chars[l])) {
7 l++;
8 } else if (!vowels.has(chars[r])) {
9 r--;
10 } else {
11 [chars[l], chars[r]] = [chars[r], chars[l]];
12 l++;
13 r--;
14 }
15 }
16 return chars.join('');
17};

Edge Cases & Common Mistakes

  • Uppercase vowels: include A, E, I, O, U.
  • No vowels: l walks to r without swapping; the string is unchanged.
  • One vowel: nothing to swap it with, so it stays.
  • Moving both pointers on a skip: only the pointer on the consonant should move, or you can step past a vowel.

Summary

Two pointers from both ends: skip consonants, swap vowels, move inward until they meet. O(n) time, O(n) space for the character array (O(1) in C and C++).

More practice: DSA interview questions with answers · patterns cheat sheet

The approach, step by step

  1. Set the pointers

    Put l at the first index and r at the last.

  2. Skip consonants

    Move l right while it is on a consonant, and r left while it is on a consonant.

  3. Swap

    When both are on vowels, swap them and move both inward. Stop when they meet.

Frequently asked questions

Why do two pointers work here?

Reversing the vowels means the first vowel swaps with the last, the second with the second-to-last, and so on. A pointer from each end finds those pairs in order: each skips consonants until it reaches a vowel, then the two swap and move inward.


Are uppercase vowels included?

Yes. LeetCode 345 counts a, e, i, o, u in both cases, so "aA" becomes "Aa". Forgetting the uppercase set is the most common wrong answer.


Why is the space O(n)?

Strings are immutable in Python, Java and JavaScript, so the characters are copied into an array to swap them. In C and C++ the string can be changed in place, so the extra space is O(1).

New to the technique behind this problem? Watch it run step by step:

Two Pointers Visualization

Applying for software engineering roles? Free, no sign-up:

AI resume checker: match your resume to the job description