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
- Declare
lowandhighasints, both set tonums[0]. - Loop over the list with
foreach (int num in nums). - Update the smallest. If
num < low, setlow = num. - Update the largest. If
num > high, sethigh = 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. - Return
(low, high). The parentheses build the tuple, and the order matches the tuple type:Lowfirst.
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:
| nums | Result |
|---|---|
[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
lowatint.MaxValueandhighatint.MinValuealso works, butnums[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.
