Problem overview
minAndMax receives a list of integers nums and returns a Pair<Int, Int>: the smallest number first, the largest second. The list always has at least one number, and the task asks for a single loop and no built-in min or max.
For [4, -2, 9, 0] the pair is (-2, 9). For a single number, [7], that number is both, so the pair is (7, 7). When every number is negative, as in [-5, -1, -8], the answer is (-8, -1).
Approach
Keep two variables, low and high, that hold the smallest and largest numbers seen so far. Look at each number once. If it is below low, it becomes the new low. If it is above high, it becomes the new high. When the loop ends, the two variables hold the answer.
The important choice is where they start. Starting both at 0 is wrong: with [5, 6, 7] the answer would claim a smallest value of 0, a number that is not in the list. Starting at nums[0] is always safe, because the first number is a real candidate for both. That is also why the constraint "at least one number" matters: an empty list would make nums[0] throw an exception.
Step by step
- Declare
lowandhighwithvar, both set tonums[0]. They must bevarbecause they change. - Loop over the list with
for (num in nums). - Inside the loop, an
ifreplaceslowwhennumis smaller. - Right below it, a second
ifreplaceshighwhennumis larger. Keeping them as two separateifs is the simplest way to say that every number is checked against both bounds. - After the loop, return
Pair(low, high).
The solution in Kotlin
class Solution {
fun minAndMax(nums: List<Int>): Pair<Int, Int> {
var low = nums[0]
var high = nums[0]
for (num in nums) {
if (num < low) {
low = num
}
if (num > high) {
high = num
}
}
return Pair(low, high)
}
}
Running it on the three examples prints:
(-2, 9)
(7, 7)
(-8, -1)
The first loop pass compares nums[0] with itself, which changes nothing. That is harmless, so the loop doesn't need to skip the first element.
The return type Pair<Int, Int> is how Kotlin hands back two values. The caller can unpack it: val (smallest, largest) = minAndMax(nums).
A trace
For [4, -2, 9, 0], both variables start at 4. This is what each pass of the loop leaves in them:
num=4 low=4 high=4
num=-2 low=-2 high=4
num=9 low=-2 high=9
num=0 low=-2 high=9
The list is read once from start to end, so the work grows in step with its length, and only two extra variables are needed no matter how long the list is.
Testing
Try inputs that catch a wrong starting value. For [5, 6, 7] the answer is (5, 7), and a start at 0 would give 0 instead of 5. For [3, 3, 3] it is (3, 3), since equal numbers never replace anything. For [-1000000, 1000000], the ends of the allowed range, it is (-1000000, 1000000).
Edge cases and common mistakes
- Starting at 0. It breaks lists where all numbers are positive (the low is wrong) or all negative (the high is wrong).
- Returning the pair in the wrong order. The smallest comes first.
- Using
val. Assigning to avalis a compile error.
