Start learning free

LESSON 174 OF 348 · STRINGS

Reverse Words in a String in Kotlin: split and joinToString

Practice O(n) Read the full explanation

Given an input string s, reverse the order of the words.

A word is defined as a sequence of non-space characters. The words in s will be separated by one space for simplicity.

Return a string of the words in reverse order concatenated by a single space.

Example:

Input:  input = "sky is blue"

Output:  "blue is sky"
STEP 1 OF 3
    Ctrl + Enter to check

    KOTLIN · STRINGS

    Reverse Words in Kotlin, explained

    Problem overview

    The function reverseWords receives a string, input, made of words separated by exactly one space. A word is a run of characters that aren't spaces. It must return the same words in reverse order, joined by a single space. The letters inside each word stay as they are.

    For "sky is blue" the words are sky, is and blue. In reverse order they are blue, is, sky, so the answer is "blue is sky". Reversing the whole string character by character would give "eulb si yks", which is not what is asked: only the order of the words flips.

    Approach: split, reverse the list, join

    The task has three natural stages, and Kotlin has a function for each:

    1. Split the string into a list of words, cutting at every space.
    2. Reverse the list, so the last word comes first.
    3. Join the words back into one string with a single space between them.

    The guarantee of exactly one space between words keeps this simple. Splitting on one space gives exactly the words, with no empty pieces to filter out.

    The cost is linear. Every character is copied a constant number of times, once into the words and once into the result, so the time is O(n). The list of words and the final string both hold about n characters, so the extra space is O(n) as well.

    Step by step

    1. Split and make the list mutable. input.split(" ") returns a List<String>. That type is read-only: it has no reverse() method. toMutableList() copies it into a MutableList<String>, which can be changed in place. Store the result in a val named words.
    2. Reverse in place. words.reverse() rearranges the elements of the list itself and returns Unit. Don't write words = words.reverse(): there is nothing to assign.
    3. Join and return. joinToString(" ") concatenates the elements with the given separator between them and returns the resulting String.

    The solution in Kotlin

    class Solution {
        fun reverseWords(input: String): String {
            val words = input.split(" ").toMutableList()
            words.reverse()
            return words.joinToString(" ")
        }
    }
    

    Kotlin details that matter here:

    • Read-only versus mutable lists. A List in Kotlin is a read-only view, and a MutableList can change. That is why the lesson converts the result of split first. val is still right for words, because the variable always points to the same list and only the list's contents change.
    • reverse() versus reversed(). On a mutable list, reverse() changes the list and returns nothing, while reversed() returns a new list and leaves the original alone. Without the toMutableList() step you could write input.split(" ").reversed().joinToString(" ") in a single line, which does the same job.
    • split takes a string delimiter. split(" ") splits on that exact text. It returns a List, not an array, and it keeps empty pieces when two delimiters touch.
    • joinToString's first argument is the separator. Calling it without an argument would join with ", ", which would give "blue, is, sky".

    Complexity

    Time: O(n), where n is the length of the string. Splitting scans every character, reversing the list touches each word once, and joining copies every character once.

    Space: O(n). The list holds all the words, and the result string is as long as the input, so both are proportional to n.

    Edge cases and common mistakes

    • A single word. "hello" splits into a list with one element, and the answer is "hello".
    • Empty string. "".split(" ") returns a list with one empty string, and joining it gives "".
    • Extra spaces. The statement promises one space between words, and the solution depends on it. With input such as "a b" (two spaces), the split produces an empty piece in the middle, and the output keeps both spaces: "b a". A leading space turns into a trailing one. Handling messy spacing would need a different split, for instance one that ignores empty pieces.
    • Forgetting the separator in joinToString. The default is a comma and a space, not a plain space.
    • Reversing characters instead of words. input.reversed() reverses every character, and the words come out backwards.
    • Calling reverse() on a read-only list. Without toMutableList(), the compiler can't find reverse() on a List.

    Testing

    • "sky is blue" gives "blue is sky".
    • "hello" gives "hello".
    • "a b" gives "b a".
    • "one two three four" gives "four three two one".
    • "" gives "".
    Keep going with KotlinAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free