Problem overview
The function trimmedTotal receives an array of integers, nums, with 3 to 100 numbers. It returns their sum without the smallest and the largest value. Think of a contest where each judge gives a score and the lowest and highest scores 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, and the same goes for the largest.
For [7, 9, 6, 8, 10] the smallest is 6 and the largest is 10, so the result is 7 + 9 + 8 = 24. For [5, 1, 5, 9, 1] the smallest value, 1, appears twice and only one copy is dropped, along with the 9, which leaves 5 + 5 + 1 = 11.
Approach
Instead of removing items from the array, subtract them from the total. Add up everything, find the smallest value once, find the largest value once, and subtract each of them once. Subtracting one copy of each drops exactly one smallest and one largest value, whatever the duplicates are.
Swift has methods for all three jobs: reduce(0, +) for the sum, and min() and max() for the extremes. Since the array always has at least 3 numbers, min() and max() always find a value, so the ! that unwraps their optional result is safe.
On [7, 9, 6, 8, 10] the total is 40. Subtracting the smallest (6) and the largest (10) leaves 24. Only three numbers take part in the final arithmetic, however long the array is.
Step by step
- Add everything:
let total = nums.reduce(0, +). The two extremes come off in the last step. - Find the smallest:
let smallest = nums.min()!. If the smallest value appears twice, you still get it once. - Find the largest:
let largest = nums.max()!, with the same!. - Return
total - smallest - largest.
The solution in Swift
class Solution {
func trimmedTotal(_ nums: [Int]) -> Int {
let total = nums.reduce(0, +)
let smallest = nums.min()!
let largest = nums.max()!
return total - smallest - largest
}
}
Swift details:
min()andmax()return optionals. They givenilfor an empty array. The!would crash on[], but the constraints keep the array at 3 or more numbers.- There is no
sum().reduce(0, +)starts at 0 and adds each value from left to right. - Nothing is removed from
nums. The array is a constant parameter and stays as it was. The function only does arithmetic on three numbers. - No overflow worry. At most 100 numbers of magnitude up to 1,000 give a total far inside
Int's 64-bit range.
Edge cases and common mistakes
- Exactly three numbers.
[-4, 3, -2]leaves only the middle value: the result is-2. - Repeated extremes.
[5, 1, 5, 9, 1]gives11. Removing every copy of the smallest value would give10, which is wrong. - All numbers equal.
[4, 4, 4]gives4: one 4 is the smallest, one is the largest, and one is left. - Negative numbers. The subtraction works the same way. In
[-4, 3, -2], the total is-3, and-3 - (-4) - 3is-2. - Subtracting only one of the extremes or forgetting the total are the usual slips; the sum must come first.
Testing
[7, 9, 6, 8, 10]gives24.[5, 1, 5, 9, 1]gives11.[-4, 3, -2]gives-2.[4, 4, 4]gives4.
