使用优先级队列实现大小顶堆
例题:
class MedianFinder {
PriorityQueue<Integer> left; //创建大顶堆
PriorityQueue<Integer> right; //创建小顶堆
/** initialize your data structure here. */
public MedianFinder() {
//大顶堆排序方式为降序 9、8、7、....
left = new PriorityQueue<>((n1,n2)->n2-n1);
//小顶堆排序方式为升序1、2、3、...
right = new PriorityQueue<>();
}
/**
*
每次添加时,优先加入大顶堆,然后加入小顶堆,可以理解为有A、B两个筐
每次加入水果时,先加入A筐,然后将A筐里最好的那一个水果加入B筐,接着为 了不让A筐里没有水果,让相差数不为1,相当于一个临界的中位数,如果相差为1了,那么将B框里最差的那个水果还到A框中。每次加入水果时,重复这个操作。
全部水果加进去后,最好两个框里水果排序(1、2、3、4、5、6、7、8):
A:4、3、2、1 (顶为4)
B:5、6、7、8 (顶为5)
B框中最差的水果比A框中最好的水果还要好,那么临界中位值就出来了,
如果B比A大1,那么中位数就是B框的顶,否则就是A框顶和B框顶的和
*/
public void addNum(int num) {
left.add(num);
right.add(left.poll());
if(right.size()-left.size()>1){
left.add(right.poll());
}
}
public double findMedian() {
if(right.size() > left.size()) return right.peek();
return (double)(left.peek() + right.peek())/2;
}
}
/**
* Your MedianFinder object will be instantiated and called as such:
* MedianFinder obj = new MedianFinder();
* obj.addNum(num);
* double param_2 = obj.findMedian();
*/
原题链接
另外对于优先级队列的一些问题
当优先级队列加入元素时,如果不指定,默认为升序,否则为降序
当加入元素之后进行遍历时,优先级队列输出的结果不一定会按顺序排列,但是进行poll操作取出后的元素,都是按顺序排列的,他只会让需要的元素在队列的顶
import java.util.Comparator;
import java.util.PriorityQueue;
public class Demo{
public static void main(String[] args) {
PriorityQueue<Integer> left = new PriorityQueue<>(Comparator.reverseOrder());
PriorityQueue<Integer> right = new PriorityQueue<>();
for (int i = 0; i < 10; i++) {
left.add(i);
right.add(i);
}
System.out.println("降序序列:");
for (int i : left){
System.out.print(i+" ");
}
System.out.println();
while (!left.isEmpty()){
System.out.print(left.poll()+" ");
}
System.out.println();
System.out.println("升序序列:");
for (int i : right){
System.out.print(i+" ");
}
}
}
输出结果
降序序列:
9 8 5 6 7 1 4 0 3 2
9 8 7 6 5 4 3 2 1 0
升序序列:
0 1 2 3 4 5 6 7 8 9
for循环内加入顺序反过来同理。