Start learning free

LESSON 91 OF 414 · FREE CODING INTERVIEW QUESTIONS

Minimum Value of Three in Rust: Comparing Without min

Practice Read the full explanation

Given 3 integers A, B and C, return the smallest number.

You are not allowed to use built-in functions such as min

Example 1:

Input: A = 7, B = 4, C = 9
Output: 4

Example 2:

Input: A = 3, B = 8, C = 3
Output: 3


There are three candidates to the solution: A, B and C. We should try out each of them until we find the correct one. How can we check if A is the solution? What should happen for A to be the minimum value?

A is the minimum value if A <= B and A <= C. We can write an if statement checking these conditions and if they hold, return A:
if A is at most B and A is at most C: return A
What if the conditions don't hold and A is not the solution? What should we do next?

We should test B. Similarly, B is the minimum value if B <= A and B <= C. We can write an if statement checking these conditions and if they hold, return B:
if A is at most B and A is at most C: return A
if B is at most A and B is at most C: return B
What if not even B is the solution?

Then, it's clear that C is the solution, so we should return C. We don't even need to check the conditions anymore:
if A is at most B and A is at most C: return A
if B is at most A and B is at most C: return B
otherwise: return C


While the solution above is very good, we propose another one which is more scalable (i.e. works better for a larger number of values). It involves going throught the numbers and using a variable minVal to store the minimum one found so far:
minVal = A
if B is less than minVal: minVal = B
if C is less than minVal: minVal = C
return minVal
Please watch the video solution for a better understanding of this solution.

STEP 1 OF 5
    Ctrl + Enter to check

    RUST · FREE CODING INTERVIEW QUESTIONS

    Minimum Value Of Three in Rust, explained

    Problem overview

    The function min_value receives three i32 integers, a, b and c, and returns the smallest of them. The task forbids built-in helpers such as min, so the comparison has to be written by hand.

    With a = 7, b = 4 and c = 9 the answer is 4. With a = 3, b = 8 and c = 3 the answer is 3: when the smallest value appears twice, you return it once, and it doesn't matter which copy you pick.

    Approach: keep the smallest value seen so far

    One way is to test each candidate: a is the answer if a <= b and a <= c, then b under the same kind of test, and otherwise c. That works, but every extra number would need a longer condition.

    The version in this lesson scales better. It keeps one variable, min_val, that always holds the smallest value looked at so far:

    1. Start by assuming a is the smallest, since it is the only number seen.
    2. Look at b. If it is smaller than min_val, it becomes the new smallest.
    3. Look at c the same way.
    4. After the last comparison, min_val holds the smallest of all three.

    With 4 numbers you would add one more if; with 1,000 numbers you would replace the if statements with a loop. The idea does not change.

    Trace it on a = 7, b = 4, c = 9. min_val starts at 7. Since 4 < 7, it becomes 4. Since 9 < 4 is false, it stays 4. The function returns 4.

    Step by step

    1. Declare min_val with let mut and set it to a. The mut keyword is required because later steps assign a new value to it.
    2. Compare b with min_val. The test is strictly "less than". An equal value would change nothing anyway, so the extra assignment is skipped.
    3. Assign b to min_val inside that if.
    4. Write a second, separate if for c. It must not be an else branch of the first one. Even when b replaced a, c still has to be compared with the new minimum.
    5. Return min_val.

    The solution in Rust

    impl Solution {
        fn min_value(a: i32, b: i32, c: i32) -> i32 {
            let mut min_val = a;
            if b < min_val {
                min_val = b;
            }
            if c < min_val {
                min_val = c;
            }
            return min_val;
        }
    }
    

    The Rust details in these few lines:

    • Variables are immutable by default. Without mut, the line min_val = b; fails to compile with "cannot assign twice to immutable variable". Rust even suggests adding mut.
    • No parentheses around conditions. Rust writes if b < min_val {, and the braces are mandatory, even for a one-line body.
    • The condition must be a bool. Rust doesn't treat numbers as true or false, so if min_val would not compile.
    • return is optional at the end. The last expression of a function, written without a semicolon, is returned automatically. Writing min_val alone as the final line is the usual Rust style, and return min_val; means the same thing here.
    • Parameters are copied. An i32 is a small value that is copied when passed, so changing min_val never affects the caller's variables.

    Edge cases and common mistakes

    • Negative numbers. min_value(-5, -9, -1) returns -9. Starting min_val at a rather than at a fixed number is what makes every input work. A start value of 0 would wrongly return 0 for 7, 4, 9.
    • Equal values. min_value(3, 8, 3) returns 3, and min_value(5, 5, 5) returns 5.
    • Using else if for the second check. With a = 9, b = 4, c = 2, the first if sets min_val to 4, and an else if would then skip c and return 4 instead of 2.
    • Largest and smallest values. min_value(i32::MAX, i32::MIN, 0) returns i32::MIN. Comparisons can't overflow, unlike arithmetic.

    Testing

    • min_value(7, 4, 9) gives 4.
    • min_value(3, 8, 3) gives 3.
    • min_value(1, 2, 3) gives 1, the case where a never gets replaced.
    • min_value(9, 4, 2) gives 2, the case where both if statements fire.
    • min_value(-5, -9, -1) gives -9.
    Keep going with RustAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free