Start learning free

LESSON 201 OF 414 · STRINGS

Reverse Words in Scala: split, reverse and mkString

Practice O(n) Read the full explanation

Given a string input, reverse the order of the words.

A word is defined as a sequence of non-space characters. The words in input 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

    SCALA · STRINGS

    Reverse Words in Scala, explained

    Problem overview

    The method reverseWords receives a String named input made of words separated by single spaces. It returns a string with the same words in the opposite order, again separated by single spaces. A word is any run of non-space characters.

    For "sky is blue" the answer is "blue is sky". Only the order of the words changes. The letters inside each word stay as they were, which separates this task from reversing the whole string character by character.

    Approach: break into words, flip the list, join

    The task becomes three small operations on collections:

    1. Cut the string into its words.
    2. Reverse the order of that collection.
    3. Glue the words back together with one space between them.

    Scala has a method for each. split cuts a string at a separator, reverse flips an array and mkString joins the elements into one string with a separator of your choice.

    The simplification the task gives is what makes this safe: the words are separated by exactly one space. Splitting on a single space therefore yields exactly the words, with nothing empty in between.

    Step by step

    1. Split the input with split(" ") and store the resulting array of strings in a val named words. For "sky is blue" this is the three-element array sky, is, blue.
    2. Reverse the array. words.reverse returns a new array in the opposite order and leaves words unchanged. Keep it in a val named reversed.
    3. Join with spaces. reversed.mkString(" ") puts one space between neighbouring elements and none at either end. As the last expression of the method, it is the returned value.

    The solution in Scala

    class Solution {
        def reverseWords(input: String): String = {
            val words = input.split(" ")
            val reversed = words.reverse
            reversed.mkString(" ")
        }
    }
    

    The Scala details worth knowing:

    • split returns an Array[String]. Arrays in Scala are mutable and fixed in size, and they are indexed with parentheses, as in words(0). The array type comes from Java, but methods like reverse and mkString are available through Scala's collection library.
    • reverse makes a new array. It doesn't reorder words in place. That is why the result needs a name of its own, and it also means the original array is still usable afterwards.
    • mkString takes a separator. mkString(" ") joins elements with a space in between. A version with three arguments, mkString("[", ",", "]"), adds a start and an end marker too. Printing an array directly with println(words) does not show its elements; it prints a type-and-address text, so use mkString when you want to see the contents.
    • No return needed. The method's value is the value of its last expression.
    • A shorter form. The three steps chain: input.split(" ").reverse.mkString(" "). The named steps in the lesson make each stage visible.

    Complexity

    Let n be the length of the string.

    Time: O(n). split scans the string once, reverse touches each word once, and mkString copies every character once into the result.

    Space: O(n). The array of words, the reversed array and the final string each hold a copy of the text, so memory grows in proportion to the input.

    Edge cases and common mistakes

    • A single word. "one" splits into one element, which reverses to itself, so the result is "one".
    • Empty string. "".split(" ") gives an array with one element, the empty string, so the method returns "".
    • Repeated spaces. The task promises one space between words, and the solution relies on it. With two spaces in a row, split(" ") produces an empty string between the words, so "a b" comes back as "b a", double space included. Splitting on " +" would treat any run of spaces as one separator, but that is beyond what this task needs.
    • Leading and trailing spaces. These are outside the task as well. For the record, a leading space produces an empty first element, while trailing empty strings are dropped by split.
    • Reversing the characters instead. input.reverse on the string gives "eulb si yks", which reverses every word too.
    • Joining with the wrong separator. mkString with no argument glues the words together with nothing between them, giving "blueissky".

    Testing

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