Pattern: Array / String (built-ins). Hand-rolled version uses Two Pointers → start and end of a chunk
Difficulty: Medium
Time: O(n) | Space: O(n) for the word list

Problem

Reverse the order of the words in a string.
" the sky is blue " → "blue is sky the"
Leading, trailing and repeated spaces must all disappear. Exactly one space between words.

Core idea

Split into words, reverse the list, join with one space.

  1. Split the string into words and throw away the empty bits.
  2. Reverse the list of words.
  3. Join them back with exactly one space.

Code (TypeScript)

Built-in version (the expected answer)

function reverseWords(s: string): string {
  return s
    .split(" ")
    .filter((w) => w !== "")
    .toReversed()
    .join(" ");
}

No .trim() needed. The filter already removed every empty string, so there’s nothing left to trim.

By hand: scan right to left with two pointers

function reverseWords(s: string): string {
  const reversedWords: string[] = [];
  let p = s.length - 1;
 
  while (p >= 0) {
    // 1. skip spaces
    if (s[p] === " ") {
      p--;
      continue;
    }
 
    // 2. mark where the word ends
    const end = p;
 
    // 3. move left until a space (or the start): that's where the word begins
    while (p >= 0 && s[p] !== " ") p--;
 
    // 4. the word is s[p+1 .. end]
    reversedWords.push(s.slice(p + 1, end + 1));
  }
 
  return reversedWords.join(" ");
}

Reading from the right means the words come out already reversed. No reverse step needed.

Why end + 1 and p + 1?

slice(start, stop) includes start and excludes stop.

index:  0 1 2 3 4 5 6
char:   t h e   s k y

After the inner loop: end = 6 (the y) and p = 3 (the space).

  • s.slice(4, 6) → "sk" ❌ the y is cut off

  • s.slice(4, 7) → "sky" ✅

  • end + 1 → so the last letter is included.

  • p + 1 → p stopped on the space, so the word starts one after it.

Python’s s[a:b] works the same way.

Gotchas

  • split(" ") leaves empty strings for repeated spaces → filter them out. (split(/\s+/) after trim() also works.)
  • Python’s s.split() with no argument handles messy spaces for you. s.split(" ") does not.
  • Use ===, not ==.
  • Type the array: const words: string[] = [], otherwise it’s any[].
  • Name pointers for what they hold: end reads better than p2.
  • Test: leading/trailing spaces, several spaces between words, a single word, a single letter.

Was this a two-pointer question?

No. LeetCode 75 lists it under Array / String, so the split solution is the expected one.
Two pointers only matters for the follow-up: “O(1) extra space if the string is mutable”.

Follow-up: O(1) extra space (C++ / char arrays only)

  1. Reverse the whole string: "the sky" → "yks eht"
  2. Reverse each word in place: "yks eht" → "sky the"
  3. Squeeze out extra spaces with a read pointer and a write pointer.

JS/TS strings are immutable, so this trick doesn’t apply there. Both JS versions above are already optimal.

Same idea shows up in