Problem overview
The function reverse takes an IntArray named nums and returns the same integers in reverse order as a List<Int>. The built-in reversing helpers are off limits, so the loop has to be written by hand.
For nums = [2, 9, 1, 5, 8] the answer is [8, 5, 1, 9, 2]: the last element comes first and the first element comes last.
Approach
The array isn't modified. Instead, build a new list by visiting the array from its last index down to index 0, adding each element as you go. The first element added is the last element of nums, so the new list ends up reversed.
For the example, the valid indices are 0 to 4, so the loop visits 4, 3, 2, 1, 0 and adds 8, 5, 1, 9, 2 in that order.
Step by step
- Create an empty list.
mutableListOf<Int>()namedansweris the collector. It needs to be mutable so elements can be added. - Loop backwards over the indices. The last valid index is
nums.size - 1, and the loop ends at 0. In Kotlin,downTobuilds a descending range that includes both ends. - Add each element.
answer.add(nums[i])appends the element at the current index. Because the indices go down, the elements arrive in reverse. - Return the list once the loop is finished.
The solution in Kotlin
class Solution {
fun reverse(nums: IntArray): List<Int> {
val answer = mutableListOf<Int>()
for (i in nums.size - 1 downTo 0) {
answer.add(nums[i])
}
return answer
}
}
Kotlin details worth knowing here:
- Precedence in
nums.size - 1 downTo 0.downTois an infix function, which binds more loosely than arithmetic, so this means(nums.size - 1) downTo 0. No parentheses are needed. - Ranges are directional.
0..4counts up and4 downTo 0counts down. A range written the wrong way round, such as4..0, is simply empty; it doesn't count down. UsedownTofor descending loops. Addstep 2to skip:4 downTo 0 step 2visits 4, 2, 0. - Types. The input is a primitive
IntArrayand the output aList<Int>. The function declares the read-onlyListtype for its result, but the object it builds is aMutableList, which is what letsaddwork inside the function. - Input unchanged. The function only reads
nums, so the caller's array keeps its original order.
Complexity
Time: O(n), where n is nums.size. The loop makes n passes, and each pass reads one element and appends it, which takes constant time on average.
Space: O(n) for the new list. A reversal that swaps elements inside the array would need only O(1) extra space, but this lesson returns a new list, so the copy is part of the result.
Edge cases and common mistakes
- Empty array. The range
-1 downTo 0is empty, because it has to count down from -1 and 0 is above it. The loop never runs and the result is an empty list. - One element. The loop runs once, and the result equals the input.
- Starting at
nums.size. The last valid index isnums.size - 1. Starting one higher throwsArrayIndexOutOfBoundsExceptionon the first pass. - Stopping at 1. Ending the range at
1instead of0drops the first element ofnumsfrom the result. - Using
..with reversed bounds.for (i in nums.size - 1..0)looks like a backwards loop but isn't. For a five-element array it is4..0, which is empty. Worse, for an empty array it is-1..0, which is not empty and would try to readnums[-1].
Testing
[2, 9, 1, 5, 8]returns[8, 5, 1, 9, 2].[7]returns[7].- An empty array returns
[].