On this page

Reverse Only Letters

7 min read•Skip-and-Swap Variant
Reverse only the letters in a string while every non-letter character stays exactly where it started - the same two-pointer swap, with a skip condition added on each side.

Problem Statement

Reverse only the letters in a string. Everything else (numbers, symbols, spaces) stays exactly where it is.

Example 1:
Input: s = "ab-cd"
Output: "dc-ba"
Explanation: Only the letters swap places, the dash stays put.
Example 2:
Input: s = "a-bC-dEf-ghIj"
Output: "j-Ih-gfE-dCba"
Explanation: Same idea with more letters and more dashes.

Brute Force

Pull out just the letters, reverse them, then place them back into the letter positions one by one. It works, but you're building extra lists to do it.

string reverseOnlyLetters(string s) {
vector<char> letters;
for (char c : s) {
if (isalpha(c)) letters.push_back(c);
}
reverse(letters.begin(), letters.end());
int j = 0;
for (int i = 0; i < s.size(); i++) {
if (isalpha(s[i])) {
s[i] = letters[j++];
}
}
return s;
}

Time: O(n)    Space: O(n) — the extra letters list is what we want to avoid.

Better Approach: Two Pointers

Same idea as reversing a plain string — one pointer at each end, moving inward. The only difference: before swapping, skip any character that isn't a letter.

string reverseOnlyLetters(string s) {
int left = 0;
int right = s.size() - 1;
while (left < right) {
if (!isalpha(s[left])) {
left++;
} else if (!isalpha(s[right])) {
right--;
} else {
swap(s[left], s[right]);
left++;
right--;
}
}
return s;
}

Complexity

Time: O(n)

Every step moves a pointer forward — skip or swap — so we never revisit a character.

Space: O(n)

We still need to turn the string into a list of characters first, since strings can't be edited in place.

Common Mistake

Forgetting to move the pointer in the skip step. If left or right doesn't move past a non-letter, the loop never ends.

How to Explain It in an Interview

How to Explain it in an Interview

The 30-Second Spoken Pitch
"It's the same two-pointer swap as reversing a plain string, but before swapping, each pointer checks if it's on a letter. If not, it just moves inward without swapping. Once both pointers land on letters, swap them and move both in. This way every non-letter stays put, and only the letters get reversed."
If the Interviewer Probes Deeper:
What if both sides are non-letters at once?

Only one side moves per step — check left first, then right. It still finishes correctly, just one step at a time.

What about a string with no letters?

The pointers just skip past everything until they cross, and nothing changes.

Next TopicLongest Palindromic Substring