Problem overview
The method reverse receives an array of integers, nums, and returns a new array with the same integers in the opposite order. The task asks you to write the loop yourself instead of calling a built-in such as reversed().
For nums = [2, 9, 1, 5, 8] the result is [8, 5, 1, 9, 2]. The last element comes first, then the one before it, and so on down to the first element.
Approach
Build a new array by reading nums from the end to the start. The last valid index is nums.count - 1 and the first is 0. Visit those indices in descending order and append each element to the new array. Because the elements are appended in that order, the new array is the reverse of the input.
Swift's range operators 0..<n and 0...n only count upward, so counting down needs another tool. The function stride(from:through:by:) produces a sequence that steps by a chosen amount, and a negative step counts down.
Step by step
- Create the result array. It will receive elements one by one, so declare it with
var.[Int]()creates an empty array of integers. - Loop from the last index down to 0.
stride(from: nums.count - 1, through: 0, by: -1)starts at the last index and subtracts 1 each time.throughincludes the end value, so0is visited. The loop variable is namedindex. - Append the element at that index.
answer.append(nums[index])copies the element into the next free slot of the result. - Return the result after the loop has finished.
The solution in Swift
class Solution {
func reverse(_ nums: [Int]) -> [Int] {
var answer = [Int]()
for index in stride(from: nums.count - 1, through: 0, by: -1) {
answer.append(nums[index])
}
return answer
}
}
Swift details worth knowing:
throughagainstto.stride(from: 4, through: 0, by: -1)gives4, 3, 2, 1, 0.stride(from: 4, to: 0, by: -1)stops before the end value and gives4, 3, 2, 1, so the first element would be skipped.- The step sign must match the direction. A negative step counts down. With a positive step and
fromlarger thanthrough, the sequence is empty. - Ranges can't count down. A range such as
5...0is a runtime error, because a range's lower bound can't be above its upper bound. Usestridefor descending loops. - The input is not modified. Arrays are value types, so
numsis the caller's data, and the method only reads it. - Empty arrays work without a special case. For an empty array,
nums.count - 1is-1, andstride(from: -1, through: 0, by: -1)is an empty sequence, so the loop body never runs.
Complexity
Time: O(n), where n is the length of nums. The loop visits each index once, and each append is amortized constant time.
Space: O(n) for the new array, which holds a copy of every element.
Edge cases and common mistakes
- Empty array. The result is
[]. - One element.
[7]stays[7]. - Starting at
nums.count. That index is one past the end, and reading it stops the program with an index-out-of-range error. - Using
toinstead ofthrough. The first element ofnumsis never added, so[2, 9, 1, 5, 8]would give[8, 5, 1, 9]. - Forgetting the negative step. With
by: 1the sequence is empty, and the method returns an empty array for every input. - Using the built-in.
reversed()would give the right answer, but the task is to write the loop yourself.
Testing
[2, 9, 1, 5, 8]gives[8, 5, 1, 9, 2].[1, 2]gives[2, 1].[7]gives[7].[]gives[].
