Skip to main content

Reverse Words in a String

Given a string s, reverse the words.

Note: You may assume that there are no leading or trailing whitespaces and each word within s is only separated by a single whitespace.

Example(s)​

Example 1:

Input: s = "The Daily Byte"
Output: "Byte Daily The"
Explanation:
Original: "The Daily Byte"
Reversed: "Byte Daily The"

Example 2:

Input: s = "Hello World"
Output: "World Hello"
Explanation:
Original: "Hello World"
Reversed: "World Hello"

Example 3:

Input: s = "a good example"
Output: "example good a"
Explanation:
Original: "a good example"
Reversed: "example good a"

Solution​

There are multiple approaches:

  1. Split, Reverse, Join: Simple and intuitive
  2. Two Pointers: Extract words and reverse order
  3. Stack: Push words onto stack, pop to reverse

JavaScript Solution - Split/Reverse/Join

/**
* Reverse words in a string
* @param {string} s - Input string
* @return {string} - String with words reversed
*/
function reverseWords(s) {
// Split by space, reverse array, join with space
return s.split(' ').reverse().join(' ');
}

// Test cases
console.log('Example 1:', reverseWords("The Daily Byte")); 
// "Byte Daily The"

console.log('Example 2:', reverseWords("Hello World")); 
// "World Hello"

console.log('Example 3:', reverseWords("a good example")); 
// "example good a"

console.log('Test 4:', reverseWords("single")); 
// "single"
Output:
Click "Run Code" to execute the code and see the results.

Alternative Solution (Two Pointers)​

Here's a two-pointer approach that doesn't use built-in split:

/**
* Two pointers approach
*/
function reverseWordsTwoPointers(s) {
const words = [];
let i = 0;

while (i < s.length) {
// Skip spaces
while (i < s.length && s[i] === ' ') {
i++;
}

if (i >= s.length) break;

// Find end of word
let j = i;
while (j < s.length && s[j] !== ' ') {
j++;
}

// Extract word
words.push(s.substring(i, j));
i = j;
}

// Reverse and join
return words.reverse().join(' ');
}

Alternative Solution (In-Place with Two Passes)​

For languages that support mutable strings, we can reverse in-place:

/**
* In-place approach (if string was mutable)
* This creates a new string but shows the logic
*/
function reverseWordsInPlace(s) {
// Convert to array for mutability
const chars = s.split('');

// Reverse entire string
reverse(chars, 0, chars.length - 1);

// Reverse each word
let start = 0;
for (let i = 0; i <= chars.length; i++) {
if (i === chars.length || chars[i] === ' ') {
reverse(chars, start, i - 1);
start = i + 1;
}
}

return chars.join('');
}

function reverse(arr, left, right) {
while (left < right) {
[arr[left], arr[right]] = [arr[right], arr[left]];
left++;
right--;
}
}

Complexity​

  • Time Complexity: O(n) - Where n is the length of the string. We visit each character at most twice.
  • Space Complexity:
    • Split/Reverse/Join: O(n) - For the array of words
    • Two Pointers: O(n) - For storing words
    • In-Place: O(1) extra space (if string was mutable)

Approach​

The simplest solution uses split, reverse, and join:

  1. Split: Split the string by spaces to get an array of words
  2. Reverse: Reverse the array of words
  3. Join: Join the reversed array with spaces

Key Insights​

  • Split by space: Separates words into an array
  • Reverse array: Changes word order
  • Join with space: Reconstructs the string
  • Simple and readable: Most intuitive approach
  • O(n) time: Optimal (must process all characters)

Step-by-Step Example​

Let's trace through Example 1: s = "The Daily Byte"

Step 1: Split by space
s.split(' ') = ["The", "Daily", "Byte"]

Step 2: Reverse array
["The", "Daily", "Byte"].reverse() = ["Byte", "Daily", "The"]

Step 3: Join with space
["Byte", "Daily", "The"].join(' ') = "Byte Daily The"

Result: "Byte Daily The"

Visual Representation​

Example 1: s = "The Daily Byte"

Original: T h e D a i l y B y t e
β””β”€β”˜ β””β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”˜
Word1 Word2 Word3

After split: ["The", "Daily", "Byte"]

After reverse: ["Byte", "Daily", "The"]

After join: "Byte Daily The"

Result: B y t e D a i l y T h e
β””β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”˜ β””β”€β”˜
Word3 Word2 Word1

Edge Cases​

  • Single word: Returns the same word
  • Two words: Swaps the two words
  • Multiple words: Reverses all words
  • Single character words: Works correctly
  • Empty string: Returns empty string (if allowed)

Important Notes​

  • No leading/trailing spaces: Problem guarantees this
  • Single space between words: Problem guarantees this
  • Split/Reverse/Join: Simplest and most readable
  • Two pointers: More control, but more code
  • In-place: More complex, but uses less space

Comparison of Approaches​

ApproachTimeSpaceReadabilityComplexity
Split/Reverse/JoinO(n)O(n)ExcellentSimple
Two PointersO(n)O(n)GoodMedium
In-PlaceO(n)O(1)FairComplex
  • Reverse String: Reverse entire string
  • Reverse Words in a String II: Different constraints
  • Valid Palindrome: Different string problem
  • Longest Common Prefix: Different problem

Takeaways​

  • Split/Reverse/Join is the simplest approach
  • O(n) time is optimal (must process all characters)
  • Space O(n) for storing words array
  • Readable code is often better than complex optimizations
  • Built-in methods make the solution concise