Menu
DSA interview questionsQuestion 26 of 147

DSA interview question · Question 26 of 147

Reverse String: Reverse a Character Array in Place

  • Easy
  • coding
  • ~4 min
  • Medium relevance
  • 3 min read
  • Updated Oct 2026

Short answer

Put a pointer at each end, swap the two characters, and move both pointers inward until they meet. Each pair is swapped once, so it is O(n) time and O(1) extra space. Slicing with s[::-1] creates a new list, which breaks the in-place requirement unless you assign it back with s[:] = s[::-1], and even then it uses O(n) temporary memory.

On this page
  1. Problem
  2. Examples
  3. Approach 1: brute force
  4. Approach 2: optimal
  5. Tests
  6. Edge cases and pitfalls
  7. Where this shows up in data engineering

Problem

You are given a list of single-character strings. Reverse it in place: modify the list itself and use only O(1) extra memory. This is widely known as LeetCode 344, Reverse String.

Examples

["e", "t", "l"]          ->  ["l", "t", "e"]
["a", "b", "c", "d"]     ->  ["d", "c", "b", "a"]
["z"]                    ->  ["z"]

Approach 1: brute force

Build a reversed copy and write it back into the original list.

def reverse_copy(s):
    rev = []
    for i in range(len(s) - 1, -1, -1):
        rev.append(s[i])
    for i, ch in enumerate(rev):
        s[i] = ch

Complexity: O(n) time, O(n) extra space. Fails the memory requirement.

Approach 2: optimal

Key insight: reversing maps position i to position n - 1 - i, which is a set of disjoint pairs. Swap each pair once.

Walkthrough on ["a", "b", "c", "d"]:

left right List after swap
0 3 d b c a
1 2 d c b a
2 1 stop (pointers crossed)
def reverse_string(s):
    left, right = 0, len(s) - 1
    while left < right:
        s[left], s[right] = s[right], s[left]
        left += 1
        right -= 1

Complexity: O(n) time, O(1) extra space. s.reverse() does the same in C and is fine to mention.

Tests

import random

def run(f, chars):
    chars = list(chars)
    assert f(chars) is None          # in place: nothing returned
    return chars

for f in (reverse_string, reverse_copy):
    assert run(f, ["e", "t", "l"]) == ["l", "t", "e"]       # odd length
    assert run(f, ["a", "b", "c", "d"]) == ["d", "c", "b", "a"]   # even length
    assert run(f, ["z"]) == ["z"]                           # single
    assert run(f, []) == []                                 # empty
    assert run(f, ["x", "x", "y"]) == ["y", "x", "x"]       # duplicates
    assert run(f, list("héllo")) == list("olléh")           # non-ASCII

big = [chr(97 + i % 26) for i in range(100_000)]
assert run(reverse_string, big) == big[::-1]

random.seed(45)
for _ in range(300):
    chars = [random.choice("abc") for _ in range(random.randint(0, 9))]
    assert run(reverse_string, chars) == run(reverse_copy, chars) == chars[::-1]

Edge cases and pitfalls

  • s = s[::-1] inside the function rebinds a local name and leaves the caller’s list unchanged.
  • Use left < right; with <= the middle element of an odd-length list is swapped with itself, which is harmless but shows imprecision.
  • Reversing a list of code points breaks grapheme clusters such as an emoji followed by a skin-tone modifier. Mention it if the input is user text.

Where this shows up in data engineering

Rarely directly. In-place, constant-memory transformations matter when working on large buffers, for example reversing byte order when converting between big-endian and little-endian encodings in binary file readers.

By Data Career Hub Editorial · Last reviewed Oct 2026 · Python 3 solutions verified with assert-based tests

Progress is saved in this browser only. No account needed.

Search
Filter by type