思路:我想的就是排序后+前k个数,评论区大佬用到了堆相关。
public int[] getLeastNumbers(int[] arr, int k) {
if (arr.length == 0)
return null;
for (int i=0;i<arr.length-1;i++){
for (int j=i+1;j<arr.length;j++){
if (arr[i]>arr[j]){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
int[] res = new int[k];
for (int i=0;i<k;i++){
res[i] = arr[i];
}
return res;
}
思路:难啊!看评论区大佬用的大小堆解决的,建议复习昨天PriorityQueue<>相关用法并背会。看评论区大佬的解释比较易懂。
将大顶堆看作普通版,小顶堆看作实验班,始终保持小顶-大顶>=1。
新生入学先入普通班(大顶堆),此时可能会失衡,于是取大顶堆第一个元素(班上学习最好的学生)进入实验班(小顶堆);若此时实验班学生过多,取小顶堆第一个元素(班上成绩最差的学生)进入普通班(大顶堆)。取中位数时,若小顶堆比大顶堆元素多1,多的即为中位数;元素相等时,两堆顶元素取平均即为中位数。
PriorityQueue<Integer> left;//大顶堆
PriorityQueue<Integer> right;//小顶堆
public day17_2() {
left = new PriorityQueue<>((n1,n2)->n2-n1); //lambda表达式,由大到小 大根堆
right = new PriorityQueue<>();// 默认小根堆,由小到达
}
public void addNum(int num) {
left.add(num);
right.add(left.poll());
if (left.size()<right.size()-1){
left.add(right.poll());
}
}
public double findMedian() {
if (right.size()>left.size())
return right.peek();
return (double)(right.peek()+left.peek())/2;//注意强制类型转换
}