Problem overview
The function reverse takes a String named input and returns a new string with the same characters in the opposite order. For "hello" the result is "olleh". The statement allows O(n) time and O(n) extra space.
Approach: copy, then swap from both ends
A Kotlin String can't be changed after it is created, so there is no way to swap two of its characters in place. The lesson therefore copies the characters into a CharArray, which is mutable, reverses the array, and builds a new string from it. The copy is the O(n) extra space the statement allows.
Reversing the array uses two pointers. One starts at the first index and one at the last. Swapping the characters they point at puts each of them in its final place. Then both pointers move one step inward, and the process repeats until they meet or cross. Each swap fixes two positions, so about half as many swaps as characters are needed.
On "hello" the pointers start at indices 0 and 4. The first swap exchanges h and o, giving oellh. Then indices 1 and 3 swap e and l, giving olleh. The pointers then meet at index 2, the middle character, which stays where it is.
Kotlin's standard library already has reversed() for strings, so in everyday code you would call that. Writing the loop yourself teaches the two-pointer technique, which also reverses arrays and parts of arrays in place, a skill used in many other problems.
Step by step
- Copy the characters into a
val charArraywithinput.toCharArray(). Thevalonly stops the variable from being reassigned; the elements can still change. - Create
leftas avarset to 0. - Create
rightas avarset tocharArray.size - 1, the last index. - Loop while
left < right. Once the pointers meet or cross, every pair has been swapped. For an odd length, the middle character has no partner and stays. - Call
swap(charArray, left, right)in the loop. The helper is written next. - Write
swapabovereverse. It takes the array and two indices. It needs no return type, because the array is shared with the caller, so the caller sees the change. - Swap with a temporary. Save
arr[i]inc, copyarr[j]intoarr[i], then putcintoarr[j]. Without the temporary, the first assignment would overwrite a value before it is saved. - Move the pointers with
left++andright--. - Build the result with
String(charArray)and return it.
The solution in Kotlin
class Solution {
fun swap(arr: CharArray, i: Int, j: Int) {
val c = arr[i]
arr[i] = arr[j]
arr[j] = c
}
fun reverse(input: String): String {
val charArray = input.toCharArray()
var left = 0
var right = charArray.size - 1
while (left < right) {
swap(charArray, left, right)
left++
right--
}
return String(charArray)
}
}
Kotlin details worth knowing:
- Arrays are passed by reference.
swapreceives the same array object thatreverseholds, not a copy. Writingarr[i] = arr[j]insideswaptherefore changes the array the caller sees. That is whyswapreturns nothing, and its return type is the implicitUnit. - Parameters can't be reassigned. Inside
swap, you can write toarr[i]but not toarritself or toi. That is also whyreverseuses its ownvarpointers. toCharArray()copies. ChangingcharArraynever affectsinput, so the caller's string is safe.String(charArray)builds a new string from the array's characters. It also copies, so later changes to the array wouldn't show up in the string.- Characters are UTF-16 units. A symbol such as an emoji takes two units, called a surrogate pair. Reversing units swaps the two halves of the pair and produces a broken symbol. For plain letters, like in the lesson, this is not an issue.
The same helper works on any part of an array. Calling swap with two indices exchanges exactly those two characters and touches nothing else, which is why the main loop can stay so short. Splitting the work into a small, testable helper and a loop that decides which pairs to swap is a habit worth keeping.
Complexity
Time: O(n). Copying the characters is linear, the loop runs about n / 2 times with constant work in each swap, and building the string is linear.
Space: O(n). The CharArray holds n characters and the final string holds another n. The swaps themselves need only one temporary character.
Edge cases and common mistakes
- Empty string.
rightis -1, the loop never runs and the function returns"". - One character. Both pointers would be at index 0; the loop doesn't run, so
"a"stays"a". - Odd and even lengths.
"abc"becomes"cba", with the middlebuntouched. An even length such as"abcd"ends with the pointers crossed. - Loop condition
left <= right. It swaps the middle character with itself, which is harmless but unnecessary. - Swapping without a temporary. Writing
arr[i] = arr[j]and thenarr[j] = arr[i]leaves both positions holding the oldarr[j]. - Looping over the whole array. Running the pointers past the middle swaps every pair twice and restores the original order.
Testing
"hello"gives"olleh"."abc"gives"cba"."abcd"gives"dcba"."a"gives"a".""gives"".