Start learning free

LESSON 264 OF 674 · TUPLES, SORTING & BUILT-INS

Min and Max in C#: One Pass, Returning a Tuple

Practice Read the full explanation

You get a List of integers nums. Return its smallest and its largest number together, as a pair.

The smallest number comes first. The function's return type shows how your language holds the pair.

Find both in one loop. Don't use a built-in min or max function.

 

Example 1:

Input: nums = [4, -2, 9, 0]
Output: (-2, 9)
Explanation: The smallest number is -2.
The largest number is 9.

Example 2:

Input: nums = [7]
Output: (7, 7)
Explanation: The only number is both the smallest and the largest.

Example 3:

Input: nums = [-5, -1, -8]
Output: (-8, -1)
Explanation: All the numbers are below 0.
The smallest is -8, and the largest is -1.

 

Constraints:

  • nums has at least one number.
  • Every number is between -106 and 106.
STEP 1 OF 5
    Ctrl + Enter to check

    C# · TUPLES, SORTING & BUILT-INS

    Min And Max in C#, explained

    Problem overview

    MinAndMax gets a List<int> named nums and returns two numbers at once: the smallest first, then the largest. The return type is the tuple (int Low, int High), so the caller can read .Low and .High or unpack both.

    For [4, -2, 9, 0] the answer is (-2, 9). For a single number, [7], it is (7, 7): that number is both the smallest and the largest. The list always has at least one number, and the lesson asks for a single loop and no built-in Min or Max.

    Approach

    Keep two variables, the smallest and the largest number seen so far, and update them as the loop visits each number. One pass is enough because each number is compared with both.

    The important choice is where to start. Starting both at 0 breaks the lesson's own inputs: for [-5, -1, -8] the largest would come out as 0, a number that is not in the list. Starting both at nums[0] is always safe, since the first number is a real candidate for both roles. That is also why the list being non-empty matters: nums[0] on an empty list would throw.

    Step by step

    1. Declare low and high as ints, both set to nums[0].
    2. Loop over the list with foreach (int num in nums).
    3. Update the smallest. If num < low, set low = num.
    4. Update the largest. If num > high, set high = num. This is a second, separate check. With one number in the list, both conditions are false and both variables keep that number, which is the right answer.
    5. Return (low, high). The parentheses build the tuple, and the order matches the tuple type: Low first.

    The solution in C#

    class Solution {
        public (int Low, int High) MinAndMax(List<int> nums) {
            int low = nums[0];
            int high = nums[0];
            foreach (int num in nums) {
                if (num < low) {
                    low = num;
                }
                if (num > high) {
                    high = num;
                }
            }
            return (low, high);
        }
    }
    

    The method builds its result with return (low, high);. C# checks that tuple against the declared type (int Low, int High), so the parts get their names from the method signature, not from the local variables. A caller can then write var (smallest, largest) = MinAndMax(nums); and pick any names.

    Calling it looks like this. The caller chooses its own names when it unpacks the pair, and each one gets the part in the same position. The first name receives Low and the second receives High, whatever they are called:

    var (smallest, largest) = new Solution().MinAndMax(new List<int>{4, -2, 9, 0});
    Console.WriteLine(smallest + " " + largest);
    
    -2 9
    

    Complexity

    The loop visits each of the n numbers once, doing two comparisons each, so the time is O(n). Only two extra variables are used, so the extra space is O(1).

    Testing

    These results come from running the solution:

    numsResult
    [4, -2, 9, 0](-2, 9)
    [7](7, 7)
    [-5, -1, -8](-8, -1)
    [3, 3, 3](3, 3)

    Common mistakes

    • Starting at 0. It gives a wrong answer when every number is positive (the smallest would be 0) or every number is negative (the largest would be 0).
    • Reaching for a sentinel. Starting low at int.MaxValue and high at int.MinValue also works, but nums[0] needs no special constant and makes the one-number case obvious.
    • Returning (high, low). The tuple is positional, so the smallest must come first.
    Keep going with C#500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free