Mastering LeetCode Problem 0344

Problem 0344: Reverse String

Reversing a string sounds like the easiest task in the world—until the problem explicitly says:

  • The string is given as a character array.
  • You must reverse it in-place.
  • You must use O(1) extra memory.

That’s exactly what LeetCode 344 – Reverse String asks you to do.
While this problem is considered “easy”, interviewers love it because it tests:

  • Whether you respect constraints (in-place, constant space),
  • How comfortable you are with the two-pointer pattern,
  • Whether you avoid unnecessary complexity or library shortcuts.

In this post, we’ll cover:

  • Problem statement in simple terms
  • Why the obvious “Pythonic” solution is not what they want
  • The two-pointer in-place strategy
  • A clean Python implementation
  • Step-by-step walkthrough
  • Time and space complexity
  • Common mistakes in interviews
  • Key mental patterns you can reuse in other problems

1. Problem Statement

Given a character array s, reverse the array in-place.

Formal constraints:

  • s is a list of characters, e.g. ["h", "e", "l", "l", "o"].
  • You must:
    • Modify s directly.
    • Use O(1) extra memory.
    • Not return a new array.

1.1. Example 1

Input:  s = ["h","e","l","l","o"]
Output: ["o","l","l","e","h"]

1.2. Example 2

Input:  s = ["H","a","n","n","a","h"]
Output: ["h","a","n","n","a","H"]

Simple enough. But let’s look at what not to do first.


2. First Attempt: Why Simple Python Tricks Aren’t Enough

If you ignore the constraints, Python gives you multiple easy ways to reverse a sequence:

2.1. Using Slicing

s[:] = s[::-1]

Or even:

s.reverse()

Both of these:

  • Reverse the array.
  • Are concise and readable.

So why not just use them?

Because in many interview settings, and especially on LeetCode:

  • The goal is to test your algorithmic thinking, not your knowledge of built-in methods.
  • They explicitly want you to show:
    • How you handle two-pointer techniques.
    • How you implement in-place logic without extra memory.

Also, if you move to lower-level languages (C, C++, Java), these shortcuts don’t exist. The underlying idea you need is the same everywhere: swap from both ends towards the middle.


3. Core Idea: Two Pointers from Both Ends

To reverse an array in-place, the natural strategy is:

  • Swap the first and last elements.
  • Then the second and second-to-last.
  • Continue until you reach the middle.

This is exactly the two-pointer pattern:

  • left pointer:
    • Starts at the beginning (0).
  • right pointer:
    • Starts at the end (len(s) - 1).
  • While left < right:
    • Swap s[left] and s[right].
    • Move left forward.
    • Move right backward.

At the end:

  • All characters are reversed,
  • No extra array is used,
  • The operation is in-place and efficient.

4. Python Implementation (Two-Pointer In-Place)

Here’s a clean and LeetCode-compatible implementation in Python:

from typing import List

class Solution:
    def reverseString(self, s: List[str]) -> None:
        """
        Reverses the input list of characters in-place.

        :param s: List of characters representing a string
        :return: None (modifies s in-place)
        """

        left, right = 0, len(s) - 1

        # Move two pointers towards the center
        while left < right:
            # Swap characters at left and right
            s[left], s[right] = s[right], s[left]

            # Move pointers inward
            left += 1
            right -= 1

4.1. Key points:

  • The method returns None because:
    • The function modifies s directly.
    • LeetCode checks the final state of s.
  • The algorithm uses:
    • A single loop.
    • Only two indices (left, right).
    • No extra arrays.

This is exactly what interviewers want to see: simple, correct, and constraint-aware.


5. Step-by-Step Walkthrough

Let’s dry-run the function on:

s = ["h","e","l","l","o"]

Initial:

  • s = ["h","e","l","l","o"]
  • left = 0"h"
  • right = 4"o"

5.1. Iteration 1

  • left = 0, right = 4
  • s[left] = "h", s[right] = "o"
  • Swap them:
s = ["o","e","l","l","h"]
  • Move pointers:
left = 1
right = 3

5.2. Iteration 2

  • left = 1, right = 3
  • s[1] = "e", s[3] = "l"
  • Swap:
s = ["o","l","l","e","h"]
  • Move pointers:
left = 2
right = 2

5.3. Iteration 3

  • Now left = 2, right = 2
  • Condition left < right is false.
  • Loop ends.

Final array:

["o","l","l","e","h"]

The string is correctly reversed, and the operation was done entirely in-place.


6. Edge Cases and How the Algorithm Handles Them

A good interview answer always shows you’ve thought about edge cases.

6.1. Empty Array

s = []
  • left = 0, right = len(s) - 1 = -1
  • left < right0 < -1 is false.
  • The loop never runs.
  • s stays [], which is correct.

6.2. Single Character

s = ["a"]
  • left = 0, right = 0
  • left < right0 < 0 is false.
  • No swaps are needed.
  • The array remains ["a"].

6.3. Even Length String

s = ["a","b","c","d"]
  • left = 0, right = 3 → swap "a" and "d"
  • left = 1, right = 2 → swap "b" and "c"
  • left = 2, right = 1 → loop ends
  • Final: ["d","c","b","a"]

6.4. Palindrome

s = ["r","a","c","e","c","a","r"]
  • Reversing a palindrome yields the same sequence.
  • Algorithm runs, but final array equals the original.
  • Shows the algorithm is general and doesn’t rely on special properties.

7. Time and Space Complexity

7.1. Time Complexity

  • We use two pointers that move towards each other.
  • At each step, they move closer by 1 position each.
  • The number of iterations is approximately n / 2 for an array of length n.

So the time complexity is:

$\text{Time Complexity} = O(n)$

7.2. Space Complexity

  • We use only a constant number of extra variables (left, right).
  • Swaps are done in-place without extra arrays.

So the space complexity is:

$\text{Space Complexity} = O(1)$

This exactly satisfies the problem requirements.


8. Common Mistakes in Interviews

Even though this is an “easy” problem, a surprising number of candidates make mistakes. Here are some of the most common ones.

8.1. Returning a New Array

Example:

def reverseString(self, s: List[str]) -> None:
    return s[::-1]

This is incorrect for two reasons:

  • The function is supposed to return None, not a new list.
  • The problem requires in-place modification of s.

Interviewers care a lot about whether you read and respect the constraints.

8.2. Using Extra Data Structures

Something like:

temp = []
for ch in s:
    temp.insert(0, ch)
s[:] = temp

Issues:

  • Uses O(n) extra memory (temp).
  • Although it “works”, it violates the O(1) extra space requirement.
  • Also less efficient than necessary.

8.3. Off-by-One Errors with Indices

Using incorrect boundaries, e.g.:

  • Running the loop while left <= right and mishandling the middle.
  • Miscomputing right or starting left at 1 instead of 0.

Two-pointer problems are a classic source of off-by-one bugs. A clean condition like while left < right helps avoid these.

8.4. Overcomplicating the Solution

Sometimes candidates:

  • Use multiple loops,
  • Introduce unnecessary temporary arrays,
  • Or add complex conditions.

For a simple reversal, this is a red flag. Interviewers expect you to choose the simplest correct solution.


9. Why This Problem Matters

You might think:

“It’s just reversing a string. Why do interviewers care?”

Because this problem tests core fundamentals:

  • Two-pointer pattern:
    • Left and right pointers moving towards each other.
  • In-place operations:
    • Modifying input without extra memory.
  • Index management:
    • Avoiding off-by-one and boundary errors.
  • Constraint awareness:
    • Not falling back to high-level helpers when the problem clearly wants low-level thinking.

Once you internalize this pattern, you’ll see it pop up in many other problems:

  • Checking if a string is a palindrome.
  • Reversing parts of an array (e.g., rotate array segments).
  • Partitioning arrays around a pivot.
  • Merging or comparing from both ends.