Start learning free

LESSON 199 OF 415 · STRINGS

Reverse String in Swift: O(n²) Time by Prepending Characters

Practice O(n2) 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^2) time and use O(n) extra space.


STEP 1 OF 4
    Ctrl + Enter to check

    SWIFT · STRINGS

    Reverse String in Swift, explained

    Problem overview

    The method reverse(_ input: String) -> String returns the characters of input in the opposite order. For "hello" the result is "olleh". The lesson asks for O(n²) time and O(n) extra space, which tells you which approach to write: build the answer by putting each new character in front of the ones already collected.

    Approach: prepend each character

    Walk through the input from left to right and keep a result string. If every character you read is placed at the front of the result, the first character ends up last and the last one ends up first:

    read h  ->  h
    read e  ->  eh
    read l  ->  leh
    read l  ->  lleh
    read o  ->  olleh
    

    This is simple, because the loop needs no indexes. The price is time. A Swift String is a value that cannot be edited at its front, so "prepend" builds a brand new string by copying the characters that were already collected. The k-th step copies about k characters, and 1 + 2 + ... + n is about n²/2, so the whole loop is O(n²). The next lesson on this problem appends to the end instead and gets O(n).

    Step by step

    1. Start with an empty result. Declare reversedString with var, because the loop reassigns it, and set it to "".
    2. Loop over the input. A for-in loop over a string visits its characters in order. Name the loop variable character.
    3. Prepend. Assign String(character) + reversedString back to reversedString. The loop variable is a Character, and + does not join a Character with a String, so it is converted with String(...) first.
    4. Return the result after the loop.

    The solution in Swift

    class Solution {
        func reverse(_ input: String) -> String {
            var reversedString = ""
            for character in input {
                reversedString = String(character) + reversedString
            }
            return reversedString
        }
    }
    

    The Swift details worth a closer look:

    • Characters, not bytes. The loop visits Character values, each one a single visible character. A letter with a combining accent, such as "e" followed by U+0301, is one Character, so it stays together and keeps its accent after the reversal. Reversing raw bytes would break it.
    • Why String(character). Without the conversion the compiler reports that it cannot convert a value of type Character to the expected argument type String.
    • Value semantics. The method never changes input. Parameters are constants, and strings are copied on assignment, so the caller's string is untouched.
    • The empty string. The loop body never runs and the method returns "".

    Complexity

    Time: O(n²). Each of the n iterations creates a new string whose length is the number of characters read so far, and the copying adds up to about n²/2 character moves. Running the method on inputs of 20,000 and 80,000 characters shows the effect: four times the input takes roughly ten times as long.

    Space: O(n). The result holds n characters. Each intermediate string is dropped when the next one replaces it, so only a constant number of them exist at once.

    Edge cases and common mistakes

    • Appending instead of prepending. reversedString += String(character) rebuilds the original string, so "hello" stays "hello".
    • Using let. reversedString is reassigned in the loop, so it must be a var. The compiler rejects an assignment to a constant.
    • A single character. "a" comes back as "a", and "ab" as "ba".
    • Spaces and punctuation. They are characters like any other: "ab cd" becomes "dc ba".

    Testing

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