Start learning free

LESSON 152 OF 414 · LOOPS & GLOBAL VARIABLES

Max In Array in Rust: Finding the Largest Value with a Loop

Practice Read the full explanation

Given an array of integers, return the maximum value from the array.

Example:

Input: nums = [2, 7, 11, 8, 11, 8, 3, 11]
Output: 11
Explanation: The maximum value is 11

Note:

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

STEP 1 OF 5
    Ctrl + Enter to check

    RUST · LOOPS & GLOBAL VARIABLES

    Max In Array in Rust, explained

    Problem overview

    The function max_in_array receives a vector of integers, nums, and returns the largest value in it. The task asks you to write the loop yourself instead of calling a built-in maximum function, because the loop is the point of the exercise.

    For nums = [2, 7, 11, 8, 11, 8, 3, 11] the answer is 11. The value appears three times, but you only return the value, not a position or a count.

    Approach: keep the best value seen so far

    You can't know the maximum until you have looked at every element, so the function visits each one once. It keeps a single variable that holds the largest value seen so far. Whenever an element is bigger than that variable, the variable takes the new value. When the loop ends, the variable holds the maximum of the whole vector.

    The one decision to make is the starting value. Starting at 0 looks natural, but it is wrong for a vector like [-5, -2, -9]: no element is greater than 0, so the function would return 0, a number that is not in the vector. Start from the first element instead. That value really is in the vector, and every other element is compared against it.

    Step by step

    1. Declare max_val with let mut and set it to nums[0]. It needs mut because the loop will reassign it, and Rust variables are immutable unless you say otherwise.
    2. Loop over &nums with a variable n. Writing &nums borrows the vector, so the loop reads the elements without taking ownership of them.
    3. Compare inside the loop. Each n is a reference, an &i32, while max_val is a plain i32. Writing *n reads the number the reference points to, and that is what you compare with max_val.
    4. Update max_val to *n when the comparison is true.
    5. Return max_val after the loop.

    The solution in Rust

    impl Solution {
        fn max_in_array(nums: Vec<i32>) -> i32 {
            let mut max_val = nums[0];
            for n in &nums {
                if *n > max_val {
                    max_val = *n;
                }
            }
            return max_val;
        }
    }
    

    The Rust details worth a closer look:

    • References in a for loop. Looping over &nums yields &i32 items. Writing if n > max_val does not compile: the compiler reports mismatched types, expecting a reference and finding an integer. Dereferencing with *n fixes it.
    • Copying out of a reference. max_val = *n; copies the integer, which is allowed because i32 is a Copy type. The vector is untouched.
    • Why borrow at all? A loop over nums without the & moves the vector into the loop, and it can't be used afterwards. Here the function doesn't use it afterwards, so either form works, but borrowing is the habit to build.
    • return at the end. The explicit return max_val; is valid. Idiomatic Rust often leaves the final value as an expression without a semicolon, max_val, which means the same thing.

    Complexity

    Time: O(n). The loop visits each of the n elements once, and each visit does a constant amount of work.

    Space: O(1). The function stores one extra integer, max_val, no matter how large the vector is.

    Edge cases and common mistakes

    • All negative numbers. [-5, -2, -9] returns -2. A start value of 0 would return 0.
    • Starting from the smallest possible value. i32::MIN also works as a start, but nums[0] needs no extra constant and keeps the answer an actual element.
    • A single element. [42] returns 42: the loop compares the element with itself and changes nothing.
    • An empty vector. nums[0] panics with "index out of bounds: the len is 0 but the index is 0". The lesson's tests use non-empty vectors; a function meant for general use would return an Option<i32> instead.
    • Using >= instead of >. The result is the same, because assigning an equal value changes nothing. It only does extra assignments.
    • Forgetting mut. Without it, max_val = *n; is a compile error, since the variable can't be assigned a second time.

    Testing

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