Problem overview
trimmedTotal receives a list of integers nums and returns their sum without one smallest and one largest value. This is how some contests score: each judge gives a score, and the lowest and highest are dropped, so no single judge decides alone.
Only one smallest and one largest value are removed. If the smallest value appears twice, the other copy still counts, and the same goes for the largest. The list has 3 to 100 numbers.
For [7, 9, 6, 8, 10] the smallest is 6 and the largest is 10, so the answer is 7 + 9 + 8 = 24. For [5, 1, 5, 9, 1] one 1 and the 9 are dropped, leaving 5 + 5 + 1 = 11. For [-4, 3, -2] only -2 is left.
Approach
Add everything, then take away the smallest and the largest once each. Kotlin has all three tools built in: sum(), min() and max(). Each returns one number, even when the value repeats, so subtracting each of them once removes exactly one copy.
That is why a duplicate is handled for free. In [5, 1, 5, 9, 1] the total is 21, min() is 1 (not 2), max() is 9, and 21 - 1 - 9 = 11. The second 1 stays in the total.
Step by step
- Store
nums.sum()intotal. - Store
nums.min()insmallest. - Store
nums.max()inlargest. - Return
total - smallest - largest.
The solution in Kotlin
class Solution {
fun trimmedTotal(nums: List<Int>): Int {
val total = nums.sum()
val smallest = nums.min()
val largest = nums.max()
return total - smallest - largest
}
}
On the three examples it returns:
24
11
-2
The constraint of at least 3 numbers matters. min() and max() throw a NoSuchElementException on an empty list, and with fewer than three numbers the "drop two values" rule would leave nothing sensible.
Tracing Example 2
With [5, 1, 5, 9, 1] the three variables hold:
total = 21
smallest = 1
largest = 9
The result is 21 - 1 - 9 = 11. Each of the three built-ins reads the list once, so the work grows in step with the number of scores.
Why does the lesson subtract instead of building a shorter list without the two values? Because removing a value from a list means finding it and shifting everything after it. Subtracting two numbers from the total is one step each, and it can't remove the wrong copy. Sums of up to 100 numbers between -1000 and 1000 stay far below the limit of an Int, so overflow isn't a concern here.
Another way
You can sort, drop the first and last items and sum the rest:
val trimmed = nums.sorted().drop(1).dropLast(1).sum()
For [7, 9, 6, 8, 10] this also gives 24. It is correct, but sorting does more work than needed just to find two values, so the three built-ins are the better fit.
Testing and common mistakes
- All values equal. For
[4, 4, 4]the answer is 4: the total 12, minus one 4 for the smallest, minus one 4 for the largest. - Negative numbers. Example 3 shows them: the smallest is the most negative one, -4.
- Removing every copy. Filtering out every value equal to the minimum or the maximum removes both 1s in Example 2 and gives 10 instead of 11. The statement says to drop just one of each.
- Forgetting
().nums.minis not a call.
