Start learning free

LESSON 249 OF 414 · TWO POINTERS

Reverse a String in Scala: Two Pointers on a Char Array

Practice O(n) Read the full explanation

Given a string, write a function that reverses that string without using built-in functions or libraries.

Example:

Input:  "hello"

Output: "olleh"

Note:

Your algorithm should run in O(n) time and use O(n) extra space.


STEP 1 OF 9
    Ctrl + Enter to check

    SCALA · TWO POINTERS

    Reverse String in Scala, explained

    Problem overview

    The method reverse receives a string input and returns a new string with the same characters in the opposite order. The example is "hello", which becomes "olleh". The task asks for no built-in reversing helpers, and the lesson allows O(n) time and O(n) extra space.

    Approach: swap from both ends

    A Scala String is immutable: no operation changes it in place. To reverse it with swaps, first copy its characters into an array, which is mutable. The copy is where the O(n) extra space comes from.

    Then use two pointers. left starts at the first position and right at the last. Swap the two characters, move the pointers one step towards each other, and repeat while left < right. When the pointers meet or cross, every character is in its mirrored place. If the length is odd, the middle character stays where it is, and it is correct there. Finally, turn the array back into a string.

    For "hello" the array is h e l l o. The first swap exchanges positions 0 and 4 and gives o e l l h. The second exchanges positions 1 and 3 and gives o l l e h. Then left is 2 and right is 2, the loop stops, and the array reads o l l e h, the word "olleh".

    Step by step

    1. Copy the characters. val charArray = input.toCharArray creates an Array[Char]. val only stops the variable from being reassigned; the elements of the array can still change.
    2. Create left as a var equal to 0.
    3. Create right as a var equal to charArray.length - 1.
    4. Write the loop while (left < right). Once the pointers meet or cross, nothing is left to swap.
    5. Swap inside the loop with swap(charArray, left, right). The helper is written next.
    6. Declare the helper def swap(arr: Array[Char], i: Int, j: Int): Unit above reverse. It returns Unit, meaning no useful value, because the array is shared with the caller, so the caller sees the change.
    7. Implement the swap with a temporary. Save arr(i) in val c, copy arr(j) into arr(i), then put c into arr(j). Without the temporary, the first assignment would overwrite a value before it was saved.
    8. Move the pointers after the swap: left += 1 and right -= 1.
    9. Build the result with new String(charArray), which copies the characters into a new string.

    The solution in Scala

    class Solution {
        def swap(arr: Array[Char], i: Int, j: Int): Unit = {
            val c = arr(i)
            arr(i) = arr(j)
            arr(j) = c
        }
        def reverse(input: String): String = {
            val charArray = input.toCharArray
            var left = 0
            var right = charArray.length - 1
            while (left < right) {
                swap(charArray, left, right)
                left += 1
                right -= 1
            }
            return new String(charArray)
        }
    }
    

    The Scala details worth a closer look:

    • Immutable strings. Methods on a String never modify it, which is why the array is needed. input itself is left unchanged by reverse.
    • Arrays are passed by reference. swap receives the same array object that reverse holds, so writing arr(i) = arr(j) inside the helper changes the caller's array. The syntax arr(i) = x is how Scala assigns to an array element.
    • Unit is Scala's "no meaningful value" type. The last line of swap is an assignment, whose value is (), the single value of type Unit.
    • new String(charArray) calls the Java String constructor. Scala runs on the JVM and can use Java's classes directly.
    • return. The lesson ends with return new String(charArray). The expression alone as the last line would return the same value.

    Why not a built-in

    Scala strings already have a reverse method, and it would solve the task in one line. The lesson asks you to do the work yourself, because the swap-and-move pattern shows up again in many two-pointer problems: reversing an array in place, partitioning, or checking a palindrome. Learning it on a string, with the extra step of copying into an array, makes the later problems easier to read.

    Watching the pointers move

    Printing the array after each swap shows the loop at work on "hello":

    o e l l h   left=1 right=3
    o l l e h   left=2 right=2

    The loop ends after two swaps. The pointers meet on the middle letter, l, which doesn't move. A string of n characters always needs n / 2 swaps, rounded down.

    Complexity

    Time: O(n). Copying the string is O(n). The loop does at most n / 2 swaps, each constant-time, and building the result is another O(n) copy.

    Space: O(n). The character array and the new string each hold n characters.

    Edge cases and common mistakes

    • Empty string. right starts at -1, the loop never runs, and the method returns an empty string.
    • One character. Both pointers are 0, no swap happens, and "a" stays "a".
    • Two characters. "ab" needs one swap and becomes "ba".
    • Running the loop too long. With left <= right nothing breaks, since the last swap exchanges a character with itself. With a loop that runs for all n positions, each pair is swapped twice and the string comes back unchanged.
    • Swapping without a temporary. Writing arr(i) = arr(j) followed by arr(j) = arr(i) leaves both positions with the same character.
    • Characters outside the basic plane. A Char is one 16-bit unit of UTF-16. Emoji and some other symbols take two units, a surrogate pair. Reversing unit by unit puts the pair in the wrong order. For "a😀b" the string has length 4, and the result is not the string "b😀a". The lesson's tests use ordinary text, where one Char is one character.

    Testing

    • "hello" gives "olleh".
    • "" gives "".
    • "a" gives "a".
    • "ab" gives "ba".
    Keep going with ScalaAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free