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
- Create
resultas an empty vector withlet mut result = Vec::new();. It ismutbecause the loop adds to it. - 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 tonums.len()alone and not compile. - Push
nums[i]ontoresult. Rust infers the element type,i32, from the first push and from the return type. - Return
resultafter 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() - 1to0on ausizeis tricky. For an empty vector,len() - 1is0 - 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 ani32, which isCopy, sopush(nums[i])puts a copy inresult. 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 islen - 1, neverlen. - Return type. The function owns
numsand returns a different vector,result. Rust movesresultout to the caller, with no copy of the data. - Library alternatives.
nums.reverse()reverses amutvector in place, andnums.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 indexlen, andnums[len]panics with "index out of bounds". - Missing parentheses.
0..nums.len().rev()doesn't compile, becauseusizehas norevmethod. - Pushing the index.
result.push(i)would collect the positions instead of the values, and its type would be ausize, which doesn't match the return type. - Printing the original. The original
numsstays 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].
