Back to Arrays
Q39Question 39 of 109

Reverse a String Without StringBuilder: Two-Pointer Swap on Char Array

Key Concepts
  • Convert the String to a char array since Java strings are immutable and cannot be reversed in place.
  • Place a left pointer at index 0 and a right pointer at the last index; swap and step inward until they cross.
  • The loop condition left < right handles both odd-length (middle character untouched) and even-length arrays.
  • Rebuild the result with new String(charArray) since the output must also be a String.
  • Extra space is O(n) due to immutability: the char array and the new String are required by the language, not the algorithm.
  • For Unicode, reversing by char can split surrogate pairs; reverse by code point for general text.
  • This is the fundamental two-pointer reversal used as a building block in rotation, palindrome checks, and many array problems.

Definition

Put left and right pointers at the ends of a char array and swap inward until they cross.
  • Two-pointer reversal – place left at index 0 and right at the last index of a char[]; swap and step inward.
  • Immutability workaround – Java strings are immutable, so convert to char[] first, reverse, then build a new String.
  • Loop condition – while (left < right) handles both odd and even lengths without special casing.
  • O(n) time – each character is swapped at most once.
  • Space – O(n) for the char[] and the new String, dictated by immutability, not the algorithm.

The National Bank of India prints a reference code backward on a receipt for a simple checksum. Think of the characters laid out in a row of boxes. One finger at the far left and one at the far right swap their contents, then both step inward, repeating until they meet in the middle.

Understanding the Concepts

What is the problem?

Reverse a string without using StringBuilder.reverse() or any built-in reversing helper. This tests raw array manipulation and understanding of Java's immutable String class.

Why do you need a char array?

Java strings are immutable: you cannot change their characters in place. The classic in-place reversal must happen on a mutable buffer. The natural choice is char[] c = str.toCharArray(). After reversing the array, you build a new String with new String(c).

How does the two-pointer swap work?

A left pointer at index 0 and a right pointer at the last index. At each step, swap the characters at left and right using a temporary variable, then advance left forward and right backward. Continue while left < right.

TEXT
Input:  "NBOI-REF-1234"

Char[]: [N, B, O, I, -, R, E, F, -, 1, 2, 3, 4]
         L                                    R

Swap N↔4, B↔3, O↔2, I↔1, -↔-, R↔F, E stays (middle)

Result: [4, 3, 2, 1, -, F, E, R, -, I, O, B, N]
Output: "4321-FER-IOBN"

How do you implement it? (with code)

JAVA
package com.bank.util;

public class StringReverser {

    public static String reverse(String input) {
        if (input == null || input.length() <= 1) {
            return input;
        }
        char[] chars = input.toCharArray();
        int left = 0, right = chars.length - 1;

        while (left < right) {
            char temp = chars[left];
            chars[left] = chars[right];
            chars[right] = temp;
            left++;
            right--;
        }
        return new String(chars);
    }

    public static void main(String[] args) {
        String refCode = "NBOI-TXN-5678";
        System.out.println("Original: " + refCode);
        System.out.println("Reversed: " + reverse(refCode));
    }
}
TEXT
Original: NBOI-TXN-5678
Reversed: 8765-NXT-IOBN

Why does left < right handle both odd and even lengths?

For odd length, the middle character sits exactly where left equals right. Its mirror is itself, so it does not need to move, and the loop correctly stops. For even length, the pointers cross between the two central characters after the last swap. One condition covers both cases.

DIAGRAM
Odd (5):  [A, B, C, D, E]
           L           R  → swap A↔E
              L     R     → swap B↔D
                 LR       → L==R, stop. C stays.

Even (4): [A, B, C, D]
           L        R  → swap A↔D
              L  R     → swap B↔C
              R  L     → L>R, stop.

What about space complexity?

People sometimes claim this is O(1) extra space, but strictly speaking, because String is immutable, you must allocate the char array and then a new String, which is O(n). The algorithm on a mutable char array would be O(1) extra space. Being precise about this distinction shows you understand immutability.

| Context | Extra space |
|---|---|
| On a mutable char[] | O(1) (just the temp variable) |
| On a Java String | O(n) (char array + new String) |

What about Unicode and surrogate pairs?

Reversing by char can split a surrogate pair, which is a character represented by two char values (like emojis or rare scripts). This produces invalid text. For general Unicode, reverse by code point or detect and keep surrogate pairs together.

JAVA
// Safe Unicode reversal
public static String reverseUnicode(String input) {
    int[] codePoints = input.codePoints().toArray();
    int left = 0, right = codePoints.length - 1;
    while (left < right) {
        int temp = codePoints[left];
        codePoints[left] = codePoints[right];
        codePoints[right] = temp;
        left++;
        right--;
    }
    return new String(codePoints, 0, codePoints.length);
}

For plain ASCII reference codes at the National Bank of India, the char-level swap is sufficient.

What are common mistakes?

JAVA
// Wrong: modifying the String directly
String s = "hello";
s.charAt(0) = 'H';  // Compile error: strings are immutable

// Wrong: using left <= right (causes double-swap at middle for odd length)
while (left <= right) {  // harmless but wastes a swap when left==right
    swap(chars, left, right);
    left++; right--;
}
// The swap at left==right is a no-op, so it is harmless but unnecessary.

// Correct:
while (left < right) { ... }

What are the edge cases?

  • Empty string – return empty.
  • Single character – return as-is.
  • Palindrome – returns the same string.
  • Null input – return null or throw.
  • Spaces and special characters – reversed along with everything else.

Where is this reversal technique used as a building block?

  • The two-pointer reversal is a fundamental primitive used in:
  • Array rotation – triple reversal.
  • Reverse words in a string – reverse whole, then reverse each word.
  • Palindrome checks – compare characters from both ends.

What are common interview follow-up questions?

  • Can you reverse without extra space? – Not for Java String (immutability), but yes for char[] or in languages with mutable strings.
  • Reverse only vowels – move only when both pointers are on vowels.
  • Reverse words in a string – reverse whole, then reverse each word.

Visual Overview

DIAGRAM
┌──────────────────────────────────────────────────────┐
│     Two-Pointer String Reversal                      │
├──────────────────────────────────────────────────────┤
│                                                      │
│  Input: "HELLO"                                      │
│  Char[]: [H, E, L, L, O]                            │
│           L           R                              │
│                                                      │
│  Step 1: swap H ↔ O  → [O, E, L, L, H]             │
│              L     R                                 │
│  Step 2: swap E ↔ L  → [O, L, L, E, H]             │
│                LR                                    │
│  Step 3: L == R → stop (middle L untouched)          │
│                                                      │
│  Result: "OLLEH"                                     │
└──────────────────────────────────────────────────────┘

Key Takeaway

Reversing a string without StringBuilder is a two-pointer swap on a char array. Because Java strings are immutable, convert to a char array first, put a left pointer at the start and a right pointer at the end, swap and step inward until they cross, then build a new String from the reversed array.

The loop condition left < right cleanly handles both odd and even lengths. For odd length the middle character is left untouched because its mirror is itself. For even length the pointers cross after the final swap.

Be precise about space: the algorithm on a mutable array is O(1) extra, but on a Java String the char array and new String make it O(n), dictated by immutability. For Unicode text, reverse by code point to avoid splitting surrogate pairs.

In a banking project at the National Bank of India, this is a small receipt utility that prints a reversed transaction reference code as a visual checksum. The two-pointer reversal is also the building block for array rotation and reversing words in a string.

Remember one sentence: Convert the immutable String to a char array, swap from both ends inward with two pointers, and build a new String from the reversed array.

---

Share
Use ← → arrow keys to navigate