Learn/DSA Patterns
DSA PatternsStringseasy6 min read

String Reversal Tricks

Reversing a string (or parts of it) in-place solves a surprising range of problems: rotating a string, reversing word order, and cycling a sequence — all in O(n) time and O(1) extra space. The core trick is that two or three targeted reverse operations can rearrange any contiguous segment without allocating a new array.

#strings#reversal#rotation#two-pointers#in-place#beginner#interview
Table of contents

The fundamental trick

Reversing a substring in place costs O(k) for a segment of length k and uses O(1) extra space (just a swap loop). Chaining two or three reversals transforms a string in sophisticated ways without any extra allocation.

The most important pattern:

To rotate a string left by k positions:
reverse s[0..k-1], reverse s[k..n-1], reverse the whole string.


The folded newspaper story

A real-life story

You have a newspaper with two sections: Local News (pages 1–4) and Sports (pages 5–8). You want Sports first. Instead of reprinting the newspaper, you:

  1. Flip the Local News section upside down.
  2. Flip the Sports section upside down.
  3. Flip the entire newspaper upside down.

The result: Sports is now in front, in the correct order. This is exactly the three-reversal rotation trick — flip each section, then flip the whole.


The one idea to remember

The entire pattern in one sentence

Any rotation or word-order flip can be achieved by two or three in-place segment reversals: reverse each part, then reverse the whole — transforming O(n) time, O(n) space into O(n) time, O(1) space.


The reverse helper

def reverse(s: list, left: int, right: int) -> None:
    while left < right:
        s[left], s[right] = s[right], s[left]
        left  += 1
        right -= 1

Note: Python strings are immutable. Convert to list(s) first, operate, then "".join(s).


Application 1 — Rotate String left by k (LC #189 equivalent on strings)

Rotate s left by k: "abcdefg", k=2 → "cdefgab"

def rotate_left(s: str, k: int) -> str:
    n = len(s)
    k %= n               # handle k > n
    arr = list(s)
    reverse(arr, 0, k - 1)         # reverse "ab"      → "ba"
    reverse(arr, k, n - 1)         # reverse "cdefg"   → "gfedc"
    reverse(arr, 0, n - 1)         # reverse whole      → "cdefgab"
    return "".join(arr)

Frame-by-frame: s = "abcdefg", k = 2

Original:  a b c d e f g
Step 1 reverse [0,1]: b a c d e f g
Step 2 reverse [2,6]: b a g f e d c
Step 3 reverse [0,6]: c d e f g a b  ✅

Application 2 — Reverse Words in a String (LC #151)

Given " the sky is blue ", return "blue is sky the".

Approach: trim, split on whitespace, reverse the word list.

def reverseWords(s: str) -> str:
    return " ".join(s.split()[::-1])

s.split() with no argument handles multiple spaces and trims — one call does everything.

In-place O(1) space version (for languages without split, or when the interviewer asks):

def reverseWords_inplace(s: str) -> str:
    arr = list(s.strip())
    n   = len(arr)

    # Step 1: reverse entire string
    reverse(arr, 0, n - 1)

    # Step 2: reverse each individual word
    start = 0
    for i in range(n + 1):
        if i == n or arr[i] == ' ':
            reverse(arr, start, i - 1)
            start = i + 1

    return "".join(arr)

Frame-by-frame: "the sky blue"

After full reverse:  "eulb yks eht"
After word reversal: "blue sky the"

Application 3 — Check if s2 is a rotation of s1 (LC #796)

Is "cdab" a rotation of "abcd"?
Trick: s1 + s1 = "abcdabcd" — every rotation of s1 appears as a substring.

def isRotation(s1: str, s2: str) -> bool:
    if len(s1) != len(s2):
        return False
    return s2 in (s1 + s1)

One line. O(n) time (KMP under the hood for in). O(n) space for the doubled string.


Application 4 — Reverse only words of length k

def reverseKWords(words: list[str], k: int) -> list[str]:
    # reverse every group of k words
    for i in range(0, len(words), 2 * k):
        words[i: i + k] = words[i: i + k][::-1]
    return words

Where to spot this pattern

Trigger words:

  • "reverse words in a string"
  • "rotate the string / array by k positions"
  • "is one string a rotation of the other"
  • "reverse every k characters"
  • "in-place" combined with any rearrangement task

Common traps

Watch out for these

  • Not reducing k modulo n. If k >= n, k %= n gives the equivalent smaller rotation. Without this, you may reverse a negative or zero-length segment.
  • Mutating a Python string directly. Python strings are immutable. Always convert to list(s) before in-place operations.
  • Extra spaces in Reverse Words. " hello world ".split() handles leading, trailing, and multiple spaces correctly. " hello world ".split(" ") does NOT — it produces empty strings. Use the no-argument version.
  • Reversing right boundary. reverse(arr, 0, n-1) — right boundary is n-1, not n.

Remember this forever

String Reversal Tricks

Rotate left by k: reverse [0,k-1] → reverse [k,n-1] → reverse [0,n-1]

Reverse word order: " ".join(s.split()[::-1]) or full-reverse then per-word-reverse.

Rotation check: s2 in (s1 + s1) — O(n), one line.

Trap: k %= n always. Python strings are immutable — list(s) first.


Check yourself

Why does reversing the whole string, then reversing each word separately, produce the correct reversed-word-order result?

Reversing the full string puts each word in reversed character order AND reverses the order of words. Then reversing each individual word restores the correct character order within each word, leaving only the word order reversed. The two operations cancel out the character-level reversal while keeping the word-level reversal.

Why does `s2 in (s1 + s1)` detect all rotations of s1?

Every rotation of s1 by k positions starts at index k in s1 + s1. Specifically, (s1 + s1)[k : k + len(s1)] is exactly the rotation of s1 by k steps. Since k ranges from 0 to len(s1)-1, all rotations appear as contiguous substrings of s1 + s1. The in operator checks substring existence in O(n) using optimised search.


Practice problems

ProblemDifficultyWhat to noticeLink
Reverse Words in a StringMediums.split()[::-1] or three-reversal in-placeLC #151
Rotate StringEasys2 in s1 + s1 — one lineLC #796
Reverse String IIEasyReverse every first-k of 2k-blockLC #541
Rotate ArrayMediumSame three-reversal trick, but on an integer arrayLC #189

Next up: Character Frequency + Sorting — using frequency counts to sort or reorganize characters for problems like "Sort Characters by Frequency" and "Reorganize String."