Problem overview
trimmedTotal gets an ArrayBuffer[Int] called nums with 3 to 100 numbers, each between -1000 and 1000. It returns their sum without one smallest value and one largest value. Contests score this way: each judge gives a score, and the lowest and highest are dropped, so one very strict or very kind judge can't decide alone.
Only one smallest and one largest value are dropped. If the smallest value appears twice, the other copy still counts.
[7, 9, 6, 8, 10]gives24, which is 7 + 9 + 8.[5, 1, 5, 9, 1]gives11: one 1 and the 9 are dropped, leaving 5 + 5 + 1.[-4, 3, -2]gives-2.
Approach
Add everything, then take the smallest and the largest off the total once each. Subtracting a value once removes exactly one copy of it, which is the rule for repeats. The built-ins sum, min and max do each piece in one call.
Removing values from the buffer is the approach to avoid. A filter such as nums.filter(n => n != nums.min && n != nums.max) drops every copy. On [5, 1, 5, 9, 1] it leaves 5 + 5 = 10 instead of 11.
In the first example, [7, 9, 6, 8, 10], the smallest is 6 and the largest is 10, so the remaining three numbers are 7, 9 and 8. Their sum is 24. The order of the numbers in the buffer doesn't matter for this problem, because a sum doesn't depend on order.
Step by step
- Store the sum of all the numbers in a
valnamedtotal. - Store the smallest number in
smallest, withmin. - Store the largest number in
largest, withmax. - Return
total - smallest - largest.
For [5, 1, 5, 9, 1] the three built-ins give a total of 21, a smallest of 1 and a largest of 9. Then 21 - 1 - 9 is 11, which matches the example.
The solution in Scala
class Solution {
def trimmedTotal(nums: ArrayBuffer[Int]): Int = {
val total = nums.sum
val smallest = nums.min
val largest = nums.max
return total - smallest - largest
}
}
min and max return one value each, even when it appears several times, so each is subtracted once. With three or more numbers, the buffer is never empty, so min and max are safe. With three equal numbers, such as [3, 3, 3], the function gives 3: the total 9 minus one 3 minus another 3. That is correct, because one smallest and one largest value are dropped, and they are two different items.
The sum stays far from the limit of Int: at most 100 numbers of at most 1000 each.
Testing
[7, 9, 6, 8, 10] 24
[5, 1, 5, 9, 1] 11
[-4, 3, -2] -2
[3, 3, 3] 3
Common mistakes
- Removing every copy. A filter that drops all copies of the smallest and largest values gives the wrong answer when they repeat, as shown above.
- Subtracting only one extreme. Both are dropped.
- Sorting and slicing off the ends. That also works:
nums.sorted.slice(1, nums.length - 1).sumgives11for the second example, because the sorted buffer isArrayBuffer(1, 1, 5, 5, 9)and the slice skips its first and last items. But it does more work than three built-in calls.
