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:
- Split the string into a list of words, cutting at every space.
- Reverse the list, so the last word comes first.
- 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
- Split and make the list mutable.
input.split(" ")returns aList<String>. That type is read-only: it has noreverse()method.toMutableList()copies it into aMutableList<String>, which can be changed in place. Store the result in avalnamedwords. - Reverse in place.
words.reverse()rearranges the elements of the list itself and returnsUnit. Don't writewords = words.reverse(): there is nothing to assign. - Join and return.
joinToString(" ")concatenates the elements with the given separator between them and returns the resultingString.
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
Listin Kotlin is a read-only view, and aMutableListcan change. That is why the lesson converts the result ofsplitfirst.valis still right forwords, because the variable always points to the same list and only the list's contents change. reverse()versusreversed(). On a mutable list,reverse()changes the list and returns nothing, whilereversed()returns a new list and leaves the original alone. Without thetoMutableList()step you could writeinput.split(" ").reversed().joinToString(" ")in a single line, which does the same job.splittakes a string delimiter.split(" ")splits on that exact text. It returns aList, 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. WithouttoMutableList(), the compiler can't findreverse()on aList.
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"".