Start learning free

LESSON 155 OF 415 · LOOPING OVER ARRAY INDICES

Reverse Array in Swift: Counting Down with stride

Practice Read the full explanation

Given an array of integers nums, return an array containing the integers in reverse order, without using built-in functions.

Example:

Input: nums = [2, 9, 1, 5, 8]
Output: [8, 5, 1, 9, 2]

Note:

Do not use builtin functions such as reverse(), it would defy the purpose of the challenge. Write the whole code yourself.

STEP 1 OF 4
    Ctrl + Enter to check

    SWIFT · LOOPING OVER ARRAY INDICES

    Reverse Array in Swift, explained

    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

    1. Create the result array. It will receive elements one by one, so declare it with var. [Int]() creates an empty array of integers.
    2. 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. through includes the end value, so 0 is visited. The loop variable is named index.
    3. Append the element at that index. answer.append(nums[index]) copies the element into the next free slot of the result.
    4. 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:

    • through against to. stride(from: 4, through: 0, by: -1) gives 4, 3, 2, 1, 0. stride(from: 4, to: 0, by: -1) stops before the end value and gives 4, 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 from larger than through, the sequence is empty.
    • Ranges can't count down. A range such as 5...0 is a runtime error, because a range's lower bound can't be above its upper bound. Use stride for descending loops.
    • The input is not modified. Arrays are value types, so nums is the caller's data, and the method only reads it.
    • Empty arrays work without a special case. For an empty array, nums.count - 1 is -1, and stride(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 to instead of through. The first element of nums is never added, so [2, 9, 1, 5, 8] would give [8, 5, 1, 9].
    • Forgetting the negative step. With by: 1 the 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 [].
    Keep going with SwiftAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free