DSA Guide
Strings

Reverse Words in a String

Reverse word order while normalising whitespace, with a two-reversal in-place technique

MediumTwo Pointers / Double Reversal
StringTwo Pointers
Problem #151

Problem Statement

Given a string s, reverse the order of its words. A word is a maximal run of non-space characters.

The result must have words separated by a single space, with no leading or trailing spaces.

Input:  "the sky is blue"
Output: "blue is sky the"

Input:  "  hello world  "
Output: "world hello"        (leading/trailing spaces removed)

Input:  "a good   example"
Output: "example good a"     (multiple spaces collapsed)

Two jobs in one problem

Reverse the word order — the headline task.

Normalise whitespace — trim the ends and collapse runs of spaces to one. Most wrong answers get the first part right and the second part wrong.

Intuition

The direct approach

Split on whitespace, reverse the resulting list, join with single spaces. Both languages' split functions can be made to drop empty pieces, which handles the normalisation for free.

This is O(n) time and O(n) space, and it is a perfectly good answer.

The in-place approach

The classic follow-up asks for O(1) extra space, which is possible in languages with mutable strings (C++, Java's char[]). It relies on a neat identity.

The key insight — reverse twice

  1. Reverse the entire string. Now the words are in the right order, but each word's letters are backwards.
  2. Reverse each word individually. The letters come out right, and the word order stays correct.
"the sky is blue"
→ reverse everything      → "eulb si yks eht"
→ reverse each word       → "blue is sky the"

Reversing twice at different granularities cancels out at the character level while leaving the word-level reordering intact.

Python and TypeScript have immutable strings, so a true O(1) version is not achievable — but the technique is worth understanding, and it is what interviewers are probing for.

Watch it run

The double-reversal technique on "the sky is blue"
the
sky
is
blue
Original word order.
1 / 4
Two reversals at different scales produce a word-level reordering.

Approach

Split on runs of whitespace

Dropping empty pieces handles leading, trailing and repeated spaces in one step.

Solution

def reverse_words(s: str) -> str:
    """Reverse word order, collapsing whitespace to single spaces."""
    # split() with no argument splits on runs of whitespace and drops empties.
    words = s.split()
    return " ".join(reversed(words))

The manual version, which shows the whitespace handling explicitly:

def reverse_words_manual(s: str) -> str:
    words: list[str] = []
    i = len(s) - 1

    while i >= 0:
        # Skip spaces between words.
        while i >= 0 and s[i] == " ":
            i -= 1
        if i < 0:
            break

        # Collect one word, scanning right to left.
        end = i
        while i >= 0 and s[i] != " ":
            i -= 1
        words.append(s[i + 1 : end + 1])

    return " ".join(words)

Scanning from the right collects words in reversed order directly, so no separate reversal is needed.

`split(' ')` is not the same as `split()`

Python: "a b".split(" ") gives ["a", "", "b"] — the empty string between the two spaces survives, and joining would produce a double space. "a b".split() with no argument gives ["a", "b"].

TypeScript: "a b".split(' ') has the same problem. Use .trim().split(/\s+/), which both removes the ends and collapses the middle.

Forgetting trim() before the regex split is also a bug: " a b".split(/\s+/) starts with an empty string.

Complexity Analysis

Time Complexity

O(n)

Space Complexity

O(n)

  • Time — one pass to split, one to reverse, one to join.
  • SpaceO(n) for the word list and the output. In a language with mutable strings, the double-reversal approach achieves O(1) extra space.

Edge Cases

On this page