π‘ Interview Challenge: Reverse Strings with Specific Rules
I recently participated in a technical interview where I received a challenge that seemed simple at first, but had very specific rules: reverse a string in JavaScript.
The challenge seemed easy initially, but there were important details that made it much more interesting. I'll share my solution and explain the reasoning behind it.
π― The Challenge
Create a function that:
- β Reverse each word individually
- β Keep the word order in the sentence
- β Preserve special characters in their original positions (don't reverse them)
Examples
// Example 1: Simple word
reverseString('hello');
// Expected: "olleh"
// Example 2: Multiple words
reverseString('hello world');
// Expected: "olleh dlrow"
// Example 3: With special characters (they don't move!)
reverseString('he-llo');
// Expected: "ol-leh"
// Example 4: Multiple words with special characters
reverseString('hello-world test');
// Expected: "olleh-dlrow tset"
// Example 5: Special characters keep position
reverseString('a-b-c');
// Expected: "c-b-a"
Key point: Special characters (-, !, ., etc.) don't change position. Only letters are reversed around them.
π€ Problem Analysis
Let's understand better with the example "he-llo":
- Characters:
h,e,-,l,l,o - Position of special character:
-is at position 2 - Normal characters (excluding
-):h,e,l,l,o - Reversed:
o,l,l,e,h - Reinsert
-at position 2:o,l,-,l,e,hβ"ol-leh"
Strategy:
- Split the string into words
- For each word:
- Extract only alphabetic characters
- Reverse these characters
- Reinsert special characters at original positions
- Join the words back
π» My Solution
Version 1: Simple and Readable
function reverseString(str) {
return str
.split(' ') // Split by spaces
.map(word => reverseWord(word)) // Reverse each word
.join(' '); // Join back with spaces
}
function reverseWord(word) {
// Extract only alphabetic characters
const letters = word.split('').filter(char => /[a-zA-Z]/.test(char));
// Reverse the alphabetic characters
letters.reverse();
// Rebuild the word
let letterIndex = 0;
return word
.split('')
.map(char => {
if (/[a-zA-Z]/.test(char)) {
return letters[letterIndex++];
}
return char; // Special character keeps its position
})
.join('');
}
// Test
console.log(reverseString('hello world')); // "olleh dlrow"
console.log(reverseString('he-llo')); // "ol-leh"
console.log(reverseString('hello-world test')); // "olleh-dlrow tset"
How it works:
reverseString()splits the string by spaces and processes each wordreverseWord()extracts letters, reverses them, and rebuilds keeping specials in place- Uses regex
/[a-zA-Z]/to identify alphabetic characters
Version 2: More Compact
function reverseString(str) {
return str
.split(' ')
.map(word => {
const letters = word
.split('')
.filter(c => /[a-zA-Z]/)
.reverse();
let i = 0;
return word
.split('')
.map(c => (/[a-zA-Z]/.test(c) ? letters[i++] : c))
.join('');
})
.join(' ');
}
Version 3: With Custom Special Characters Support
If the interviewer wanted to specify which characters to reverse:
function reverseString(str, preserveChars = /[^a-zA-Z]/) {
return str
.split(' ')
.map(word => reverseWord(word, preserveChars))
.join(' ');
}
function reverseWord(word, preserveChars) {
// Extract only characters that are NOT preserved
const chars = word.split('').filter(char => !preserveChars.test(char));
chars.reverse();
// Rebuild
let charIndex = 0;
return word
.split('')
.map(char => (preserveChars.test(char) ? char : chars[charIndex++]))
.join('');
}
// Usage
console.log(reverseString('hello-world')); // "olleh-dlrow"
// Customize: only keep numbers
console.log(reverseString('hel3lo w0rld', /[0-9]/)); // "0lrw dl3leh"
π§ͺ Test Cases
// Basic cases
console.assert(reverseString('hello') === 'olleh', 'Simple word');
console.assert(reverseString('hello world') === 'olleh dlrow', 'Multiple words');
// With special characters
console.assert(reverseString('he-llo') === 'ol-leh', 'Hyphen in middle');
console.assert(reverseString('hello!') === 'olleh!', 'Punctuation at end');
console.assert(reverseString('h-e-l-l-o') === 'o-l-l-e-h', 'Multiple hyphens');
// Complex cases
console.assert(
reverseString('hello-world test!') === 'olleh-dlrow tset!',
'Multiple words with special chars'
);
// Empty and edge cases
console.assert(reverseString('') === '', 'Empty string');
console.assert(reverseString('a') === 'a', 'Single character');
console.assert(reverseString('!!!') === '!!!', 'Only special chars');
console.assert(reverseString('-a-b-c-') === '-c-b-a-', 'Special chars at extremes');
console.log('β
All tests passed!');
π Complexity Analysis
| Aspect | Complexity | Explanation |
|---|---|---|
| Time | O(n) | Traverses the string once |
| Space | O(n) | Creates temporary arrays |
Where n is the length of the string.
π What the Interviewer Was Looking For
In the interview, notice that the interviewer wanted to evaluate:
1. Problem Understanding
- Clarify requirements (what reverses? what doesn't?)
- Ask questions (multiple spaces? tabs? accents?)
2. Algorithmic Reasoning
- Break problem into smaller parts (word by word)
- Handle details (special characters)
3. Clean Implementation
- Readable code with clear names
- Use helper functions
- Avoid overly complex solutions
4. Testing
- Think about edge cases
- Validate your solution
π¬ During the Interview
Tips for when you receive this type of challenge:
β What to do
- π£οΈ Talk out loud - Explain your reasoning
- π€ Ask questions - "Can I assume the input is a valid string?"
- π§ͺ Test edge cases - Empty string, special characters, etc
- β»οΈ Refactor - After it works, improve the code
- π Explain - Show that you understand the solution
β What to avoid
- π Don't rush - Clarity is more important than speed
- π€ Don't stay silent - Show your thinking
- π Don't refactor indefinitely - Stop when it's good
- β Don't ignore edge cases - They matter
π Advanced Version with RegEx
If you wanted to impress more:
function reverseString(str) {
return str.replace(/\S+/g, word => {
const letters = word.match(/[a-zA-Z]/g) || [];
let i = letters.length;
return word.replace(/[a-zA-Z]/g, () => letters[--i]);
});
}
console.log(reverseString('hello-world test!'));
// "olleh-dlrow tset!"
How it works:
/\S+/g- Finds all words (without spaces)match(/[a-zA-Z]/g)- Extracts only lettersreplace(/[a-zA-Z]/g, ...)- Replaces letters keeping specials in place
π― Conclusion
This challenge seems simple, but it has several lessons:
- Clear requirements - Ask before coding
- Break problems down - Split into smaller parts
- Details matter - Special characters aren't trivial
- Testing is essential - Validate your solution
The final solution is elegant, efficient, and shows good algorithmic reasoning. This is exactly what interviewers are looking for!