Problem overview
The method trimmedTotal gets a list nums of 3 to 100 integers and returns their sum without the smallest and the largest value. It works like a contest where each judge gives a score, and the lowest and the highest are dropped so that 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, and the same is true for the largest.
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] the answer is 11: one 1 and the 9 are dropped, and 5 + 5 + 1 remains.
Approach
You don't need to remove anything from the list. Add up everything, then subtract the two extremes once each: total - smallest - largest. Subtracting a value once takes exactly one copy of it out of the sum, so repeated extremes are handled correctly without extra code.
Python has a built-in for each part: sum for the total, min for the smallest value and max for the largest.
Step by step
- Store
sum(nums)intotal. - Store
min(nums)insmallest. It returns the value once, even if the value appears twice. - Store
max(nums)inlargest. - Return
total - smallest - largest.
The solution in Python
class Solution:
def trimmedTotal(self, nums: List[int]) -> int:
total = sum(nums)
smallest = min(nums)
largest = max(nums)
return total - smallest - largest
The names total, smallest and largest were picked on purpose. Calling the total sum in a file where the built-in is used again later would hide it: the name would hold a number, and calling it fails with a TypeError.
Tracing the examples
| nums | sum | min | max | answer |
|---|---|---|---|---|
| [7, 9, 6, 8, 10] | 40 | 6 | 10 | 24 |
| [5, 1, 5, 9, 1] | 21 | 1 | 9 | 11 |
| [-4, 3, -2] | -3 | -4 | 3 | -2 |
The third row has a negative sum and a negative answer; the same arithmetic works. The list has at least 3 numbers, so min and max never see an empty list.
Another way
Sorting also works: sum(sorted(nums)[1:-1]) drops the first and the last element of the sorted list, and gives 24 for the first example and 11 for the second. It sorts the whole list to drop two values, so the three built-ins are simpler, and they pass over the list without reordering it.
Edge cases
The list always has at least three numbers, so after dropping two values, at least one remains. With exactly three numbers, the answer is the middle value, as in [-4, 3, -2], where -2 is left. If all the numbers are equal, say three 5s, then the smallest and the largest are both 5, one copy of each is dropped, and one 5 remains, which 15 - 5 - 5 gives correctly. The numbers are small (between -1000 and 1000), and Python integers don't overflow anyway.
Common mistakes
- Removing every copy of the smallest value, for example by filtering with
if num != smallest. In[5, 1, 5, 9, 1]that drops both 1s and gives 10, not 11. - Forgetting to subtract the largest value as well as the smallest.
- Naming a variable
sum,minormaxand then calling the built-in of that name.
