每个学生有两个属性 id
和 scores
。找到每个学生最高的5个分数的平均值。
样例
例1:
输入:
[[1,91],[1,92],[2,93],[2,99],[2,98],[2,97],[1,60],[1,58],[2,100],[1,61]]
输出:
1: 72.40
2: 97.40
例2:
输入:
[[1,90],[1,90],[1,90],[1,90],[1,90],[1,90]]
输出:
1: 90.00
解题思路1:
排序。按照id升序再按照score降序,最后再依次取每个id的前5项。
/**
* Definition for a Record
* class Record {
* public int id, score;
* public Record(int id, int score){
* this.id = id;
* this.score = score;
* }
* }
*/
public class Solution {
/**
* @param results a list of <student_id, score>
* @return find the average of 5 highest scores for each person
* Map<Integer, Double> (student_id, average_score)
*/
public Map<Integer, Double> highFive(Record[] results) {
// Write your code here
Map<Integer, Double> map = new HashMap<>();
if(results == null || results.length < 5)
return map;
Arrays.sort(results, new Comparator<Record>(){
@Override
public int compare(Record a, Record b){
if(a.id != b.id)
return a.id - b.id;
else
return b.score - a.score;
}
});
int reId = results[0].id;
for(int i=0; i<results.length;){
int times = 0;
int sum = 0;
while(i < results.length && results[i].id == reId && times < 5){
sum += results[i].score;
times++;
i++;
}
if(sum != 0){
map.put(reId, (double)sum/5);
reId++;
}else
i++;
}
return map;
}
}
解题思路2:
采用优先队列。使用Map<Integer, PriorityQueue<Integer>>来存储id以及id对应的score集合,始终保持优先队列只存储前5大的元素即可。
/**
* Definition for a Record
* class Record {
* public int id, score;
* public Record(int id, int score){
* this.id = id;
* this.score = score;
* }
* }
*/
public class Solution {
/**
* @param results a list of <student_id, score>
* @return find the average of 5 highest scores for each person
* Map<Integer, Double> (student_id, average_score)
*/
public Map<Integer, Double> highFive(Record[] results) {
// Write your code here
Map<Integer, Double> res = new HashMap<>();
if(results == null || results.length < 5)
return res;
Map<Integer, PriorityQueue<Integer>> map = new HashMap<>();
for(int i=0; i<results.length; i++){
if(!map.containsKey(results[i].id))
map.put(results[i].id, new PriorityQueue<Integer>());
PriorityQueue<Integer> queue = map.get(results[i].id);
if(queue.size() < 5)
queue.add(results[i].score);
else{
if(results[i].score > queue.peek()){
queue.poll();
queue.add(results[i].score);
}
}
}
for(Integer id : map.keySet()){
PriorityQueue<Integer> queue = map.get(id);
double sum = 0;
while(!queue.isEmpty())
sum += queue.poll();
res.put(id, sum/5.0);
}
return res;
}
}