持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第19天,点击查看活动详情
一、题目描述:
1491. 去掉最低工资和最高工资后的工资平均值 - 力扣(LeetCode)
给你一个整数数组 salary ,数组里每个数都是 唯一 的,其中 salary[i] 是第 i 个员工的工资。
请你返回去掉最低工资和最高工资以后,剩下员工工资的平均值。
示例 1:
输入:salary = [4000,3000,1000,2000]
输出:2500.00000
解释:最低工资和最高工资分别是 1000 和 4000 。
去掉最低工资和最高工资以后的平均工资是 (2000+3000)/2= 2500
示例 2:
输入:salary = [1000,2000,3000]
输出:2000.00000
解释:最低工资和最高工资分别是 1000 和 3000 。
去掉最低工资和最高工资以后的平均工资是 (2000)/1= 2000
示例 3:
输入:salary = [6000,5000,4000,3000,2000,1000]
输出:3500.00000
示例 4:
输入:salary = [8000,9000,2000,3000,6000,1000]
输出:4750.00000
提示:
- 3 <= salary.length <= 100
- 10^3 <= salary[i] <= 10^6
- salary[i] 是唯一的。
- 与真实值误差在 10^-5 以内的结果都将视为正确答案。
二、思路分析:
直观思路当然是先遍历一遍找到最大值,再遍历一遍找到最小值,最后再遍历一遍并在过程中跳过最大值和最小值并求和,最终得出结果。
这样整体时间复杂度是O(n*3),也就是O(n)
更有甚者想用排序,时间复杂度会直接上升到O(nlogn),对于这类只求最大最小值的简单情况,纯属弄巧成拙,徒增算法运行复杂度。
更优的解法肯定是在O(n)的解法基础上减少n的系数,也就是遍历的次数,考虑能否在一次遍历中通过额外变量收集尽可能多的信息。
三、AC 代码:
/**
* @param {number[]} salary
* @return {number}
*/
var average = function(salary) {
let max = -Infinity, min = Infinity, sum = 0;
for (const s of salary) {
sum += s;
if (s > max) max = s;
if (s < min) min = s;
}
const res = (sum - max - min) / (salary.length - 2);
return res;
};
四、参考:
【track & traning】一行代码,思路简单,性能高效接近双90 - 去掉最低工资和最高工资后的工资平均值 - 力扣(LeetCode)