Start learning free

LESSON 270 OF 671 · DESTRUCTURING, SORTING & BUILT-INS

Total Without Extremes in JavaScript

Practice Read the full explanation

You get an array of integers nums. Return their sum without the smallest and the largest value.

Some contests score this way. Each judge gives a score. The lowest and the highest score are dropped. So one very strict or very kind judge can't decide alone.

Drop only one smallest value and one largest value. If the smallest value appears twice, the other copy still counts. The same goes for the largest value.

 

Example 1:

Input: nums = [7, 9, 6, 8, 10]
Output: 24
Explanation: The smallest value is 6 and the largest is 10.
The rest add up to 7 + 9 + 8 = 24.

Example 2:

Input: nums = [5, 1, 5, 9, 1]
Output: 11
Explanation: The smallest value, 1, appears twice.
Only one 1 is dropped, and so is the 9.
5 + 5 + 1 = 11.

Example 3:

Input: nums = [-4, 3, -2]
Output: -2
Explanation: -4 is the smallest value and 3 is the largest.
Only -2 is left.

 

Constraints:

  • nums has 3 to 100 numbers.
  • Every number is between -1000 and 1000.
STEP 1 OF 4
    Ctrl + Enter to check

    JAVASCRIPT · DESTRUCTURING, SORTING & BUILT-INS

    Trimmed Total in JavaScript, explained

    Problem overview

    trimmedTotal(nums) receives an array of 3 to 100 integers and returns their sum without the smallest and the largest value. Contests score this way: every judge gives a score, and the lowest and the highest are dropped, so one very strict or very kind judge can't decide alone.

    Only one smallest value and one largest value are dropped. For [7, 9, 6, 8, 10] the smallest is 6 and the largest 10, so the rest add up to 7 + 9 + 8 = 24. For [5, 1, 5, 9, 1] the smallest, 1, appears twice. Only one 1 is dropped, and so is the 9, leaving 5 + 5 + 1 = 11.

    Approach

    Add everything, then subtract the smallest once and the largest once. Subtracting each value a single time removes exactly one copy of it, even when it repeats. Nothing needs sorting or searching for positions.

    The three pieces are built-ins: reduce for the total, and Math.min and Math.max with the spread dots for the extremes.

    Step by step

    1. Store the sum of all numbers in total: nums.reduce((sum, x) => sum + x, 0).
    2. Store the smallest number in smallest with Math.min(...nums).
    3. Store the largest number in largest with Math.max(...nums).
    4. Return total - smallest - largest.

    The solution in JavaScript

    class Solution {
        /**
        * @param {number[]} nums
        * @return {number}
        */
        trimmedTotal(nums) {
            let total = nums.reduce((sum, x) => sum + x, 0);
            let smallest = Math.min(...nums);
            let largest = Math.max(...nums);
            return total - smallest - largest;
        }
    }
    

    The dots in ...nums spread the array into separate arguments, which is what Math.min and Math.max expect. Without them they would be handed the whole array and give NaN for arrays with more than one number. The three examples return:

    24
    11
    -2
    

    For the second example, the total is 21, the smallest is 1 and the largest is 9, so 21 - 1 - 9 = 11. The third example, [-4, 3, -2], adds to -3, minus the smallest -4 and the largest 3, gives -2: subtracting a negative number adds it back.

    Testing

    Besides the statement's examples, try the smallest allowed input, three numbers such as [1, 2, 3]: the smallest is 1, the largest is 3, and what is left is 2. Try three equal numbers such as [4, 4, 4]: the total is 12, and subtracting one 4 for the smallest and one 4 for the largest leaves 4. In both cases exactly one value remains, which is the middle one.

    Complexity

    The sum, the minimum and the maximum each read the array once, so the time is O(n). The extra space is O(1) for the three numbers you keep; the spread also hands the values to the function as separate arguments, which is fine for at most 100 numbers.

    Edge cases and common mistakes

    • Dropping every copy. Removing all copies of the smallest value would turn the second example into 5 + 5 = 10. Subtracting smallest once keeps the other 1.
    • Sorting and slicing. Sorting without a compare function orders numbers as text, so [10, 9, 1].sort() gives [1, 10, 9]. Subtracting the extremes avoids that.
    • Forgetting the start value of reduce. Here the input always has at least 3 numbers, so a missing 0 would not crash. Pass it anyway: it makes the sum start from a known place, and an empty array would otherwise throw a TypeError.
    • Leaving out the dots. Math.min(nums) gives NaN for this input.
    Keep going with JavaScript500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free