class Solution { public int[] getLeastNumbers(int[] arr, int k) { if (k == 0 || arr.length == 0) { return new int[0]; } Queue<Integer> maxHeap=new PriorityQueue<>((v1,v2)->v2-v1); for(int num: arr){ if(maxHeap.size()<k){ maxHeap.offer(num); }else if(num<maxHeap.peek()){ maxHeap.poll(); maxHeap.offer(num); } } int []res=new int [maxHeap.size()]; int id=0; for(int num : maxHeap){ res[id++]=num; } return res; } }
剑指 Offer 45. 把数组排成最小的数
- 利用最小堆来,其最重要的核心就是关于 a+b<b+a这种思想,比如 1+2<2+1这种思想
class Solution { public String minNumber(int[] nums) { PriorityQueue<String> minHeap=new PriorityQueue<>((a,b)->{ return new String(a+b).compareTo(b+a); }); for(int i:nums){ minHeap.add(String.valueOf(i)); } StringBuilder res=new StringBuilder(); while(!minHeap.isEmpty()){ res.append(minHeap.poll()); } return res.toString(); } }
![]()
- 用大顶堆+小顶堆方法,可以看作大顶堆是普通班,小顶堆是实验班。数量上时刻保持 小顶-大顶<=1(两堆相等或者小顶比大顶多一个)而且实验班的学生成绩都大于普通班。
- 新学生先入普通班(大顶堆),此时可能会失去平衡了,于是取大顶堆的第一个(班里最好的学生)加入实验班(小顶堆),判断若数量过多(不是等于或多一个),取第一个(实验班里最差的学生)到普通班(大顶堆)里。 取中位数的时候,若两堆数量相等,则各取堆顶取平均,若小顶比大顶多一,则多的那一个就是中位数。
class MedianFinder { PriorityQueue <Integer> large;//大根堆 //大根堆中的元素都是小于小根堆的 PriorityQueue <Integer> small;//小根堆 //小根堆的元素都是大于大根堆的 /** initialize your data structure here. */ public MedianFinder() { large=new PriorityQueue<>((n1,n2)->{ return n2-n1; }); small=new PriorityQueue<>(); } public void addNum(int num) { //保证两个堆的元素一样,我们就只需要比较两个堆的元素个数 //如何保证小根堆的元素都大于大根堆 //首先把新的数据先放入到大根堆 //然后把大根堆的最大数放到小根堆 //保证小根堆的数都大于大根堆 //如果我们的小根堆的数量比大根堆多的不止一个 //那么就将小根堆的最小值放到大根堆 来保证平衡 large.add(num); small.add(large.poll()); if(large.size()+1<small.size()){ large.add(small.poll()); } } public double findMedian() { //我们的思想就是 来保证两个堆的数量是相同的(如果是奇数个元素,一个堆会比;另一个堆多一个数) //然后大根堆中的数都是小于小根堆中的数的 //也就是大根堆的最大数小于小根堆的最小数 //那么我们的中位数就是 如果是奇数个元素,就是多一个元素的那个数,如果是偶数,就是两个堆的 //堆顶元素的平均数 if(small.size()>large.size()){ return small.peek(); } return (double)(large.peek()+small.peek())/2; } } /** * Your MedianFinder object will be instantiated and called as such: * MedianFinder obj = new MedianFinder(); * obj.addNum(num); * double param_2 = obj.findMedian(); */