leetcode1792第232场周赛第三题,以及二维数组根据某一列进行排序
题目
一所学校里有一些班级,每个班级里有一些学生,现在每个班都会进行一场期末考试。给你一个二维数组 classes ,其中 classes[i] = [passi, totali] ,表示你提前知道了第 i 个班级总共有 totali 个学生,其中只有 passi 个学生可以通过考试。
给你一个整数 extraStudents ,表示额外有 extraStudents 个聪明的学生,他们 一定 能通过任何班级的期末考。你需要给这 extraStudents 个学生每人都安排一个班级,使得 所有 班级的 平均 通过率 最大 。
一个班级的 通过率 等于这个班级通过考试的学生人数除以这个班级的总人数。平均通过率 是所有班级的通过率之和除以班级数目。
请你返回在安排这 extraStudents 个学生去对应班级后的 最大 平均通过率。与标准答案误差范围在 10-5 以内的结果都会视为正确结果。
样例
输入:classes = [[1,2],[3,5],[2,2]], extraStudents = 2
输出:0.78333
解释:你可以将额外的两个学生都安排到第一个班级,平均通过率为 (3/4 + 3/5 + 2/2) / 3 = 0.78333 。
分析:
要让这些一定能通过的学生加入到班级里面,使得通过率有较大的提升,那么所加入的班级通过率一定不能是100%,否则加入就没有意义,通过率提升为0,。同时对于通过率不是100% 的班级,加入一个必通过的学生通过率的提升可以用加入后的通过率减去加入前的通过率。也就是:
增加量n=(y+1)/(x+1)-y/x
然后创建一个优先队列,按照上述增量计算进行排序,加入数据。之后从队列头拿到增加率最高的进行加入,重新排序,直到所有人都加进去。
最后就是循环计算出平均的通过率。
代码Java
class Solution {
public double maxAverageRatio(int[][] classes, int extraStudents) {
PriorityQueue<int[]> queue = new PriorityQueue<>(new Comparator<int[]>() {
public int compare(int[] o1,int[] o2){
//加入人到班级所提升的通过率,从大到小排序
double d1=((double)(o1[0]+1)/(double)(o1[1]+1))-(double)(o1[0])/(double)(o1[1]);
double d2=((double)(o2[0]+1)/(double)(o2[1]+1))-(double)(o2[0])/(double)(o2[1]);
if(d2>d1)
return 1;
else
return -1;
}
});
for(int[] c: classes){
queue.add(c);
}
for(int i=0;i<extraStudents;++i){
int[] tempClass=queue.poll();
tempClass[0]++;
tempClass[1]++;
queue.add(tempClass);
}
double sum=0;
while(!queue.isEmpty()){
int[] tempCla=queue.poll();
sum+=(double)tempCla[0]/(double)tempCla[1];
}
return sum/classes.length;
}
}
二维数组根据某一列进行排序
//二维数组根据某一列进行排序
int[][] ts_id = new int[][] {{1,2},{99,0},{876,9},{3,100}};
Arrays.sort(ts_id,new Comparator<int[]>() {
public int compare(int[] o1, int[] o2) {
return o1[0]-o2[0];
}
});