Start learning free

LESSON 265 OF 677 · PAIRS, SORTING & BUILT-INS

Min and Max in Kotlin: Both in One Loop

Practice Read the full explanation

You get an ArrayList 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

    KOTLIN · PAIRS, SORTING & BUILT-INS

    Min And Max in Kotlin, explained

    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

    1. Declare low and high with var, both set to nums[0]. They must be var because they change.
    2. Loop over the list with for (num in nums).
    3. Inside the loop, an if replaces low when num is smaller.
    4. Right below it, a second if replaces high when num is larger. Keeping them as two separate ifs is the simplest way to say that every number is checked against both bounds.
    5. 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 a val is a compile error.
    Keep going with Kotlin500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free