Start learning free

LESSON 159 OF 414 · LOOPING OVER ARRAY INDICES

Reverse Array in Rust: Looping Backwards with a Reversed Range

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

    RUST · LOOPING OVER ARRAY INDICES

    Reverse Array in Rust, explained

    Problem overview

    The function reverse_array receives a vector of integers, nums, and returns a new vector with the same integers in the opposite order. The task asks you to write the loop yourself instead of calling a built-in reversal.

    For nums = [2, 9, 1, 5, 8] the result is [8, 5, 1, 9, 2].

    Approach: read from the back, write to the front

    The last element of the input must come first in the output, the second to last must come second, and so on. So walk the indices of nums from the largest to the smallest, and push each element onto a new vector. The first push stores the last element, and the final push stores the first one, which gives the reversed order.

    Rust has no for loop that counts downward with a step of -1. Instead, you build the ascending range of valid indices and reverse it with .rev(). The range 0..nums.len() yields 0, 1, ..., len - 1, and (0..nums.len()).rev() yields the same numbers from the back: len - 1, ..., 1, 0. The reversed range is produced lazily, one number at a time, so nothing extra is allocated for the indices.

    Step by step

    1. Create result as an empty vector with let mut result = Vec::new();. It is mut because the loop adds to it.
    2. Loop over reversed indices. Write for i in (0..nums.len()).rev(). The parentheses matter: .rev() applies to the whole range, and without them the method call would bind to nums.len() alone and not compile.
    3. Push nums[i] onto result. Rust infers the element type, i32, from the first push and from the return type.
    4. Return result after the loop.

    The solution in Rust

    impl Solution {
        fn reverse_array(nums: Vec<i32>) -> Vec<i32> {
            let mut result = Vec::new();
            for i in (0..nums.len()).rev() {
                result.push(nums[i]);
            }
            return result;
        }
    }
    

    The Rust details worth a closer look:

    • Why not count down by hand? A countdown from nums.len() - 1 to 0 on a usize is tricky. For an empty vector, len() - 1 is 0 - 1, which wraps in an optimized build (and panics in a debug build). The reversed range has no subtraction, so an empty vector simply gives an empty loop.
    • Elements are copied. nums[i] reads an i32, which is Copy, so push(nums[i]) puts a copy in result. The input vector is not changed.
    • Half-open range. The range 0..nums.len() excludes the length. Reversing it keeps that property: the first index visited is len - 1, never len.
    • Return type. The function owns nums and returns a different vector, result. Rust moves result out to the caller, with no copy of the data.
    • Library alternatives. nums.reverse() reverses a mut vector in place, and nums.iter().rev().cloned().collect() builds a reversed copy. Both are the built-in route the task asks you to avoid here.

    Complexity

    Time: O(n). The loop runs once for each of the n elements, and each push takes constant time on average.

    Space: O(n). The result holds n integers. If you reversed the vector in place by swapping elements from both ends, you would need O(1) extra space, but this lesson asks for a new vector.

    Edge cases and common mistakes

    • Empty vector. The reversed range is empty, so the function returns an empty vector.
    • One element. [4] returns [4].
    • Palindromes. [1, 2, 1] returns an identical vector, which is correct.
    • Starting from the length. A reversed inclusive range, (0..=nums.len()).rev(), begins at index len, and nums[len] panics with "index out of bounds".
    • Missing parentheses. 0..nums.len().rev() doesn't compile, because usize has no rev method.
    • Pushing the index. result.push(i) would collect the positions instead of the values, and its type would be a usize, which doesn't match the return type.
    • Printing the original. The original nums stays in its old order. The function returns the reversed copy.

    Testing

    • [2, 9, 1, 5, 8] gives [8, 5, 1, 9, 2].
    • [4] gives [4].
    • [] gives [].
    • [1, 2, 1] gives [1, 2, 1].
    Keep going with RustAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free