import java.util.*;
public class Solution {
private int count = 0;
private PriorityQueue<Integer> minHeap = new PriorityQueue<>();
// private PriorityQueue<Integer> maxHeap = new PriorityQueue<>();
private PriorityQueue<Integer> maxHeap = new PriorityQueue<Integer>(15, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
public void Insert(Integer num) {
if (count %2 == 0) {//当数据总数为偶数时,新加入的元素,应当进入小根堆
//(注意不是直接进入小根堆,而是经大根堆筛选后取大根堆中最大元素进入小根堆)
//1.新加入的元素先入到大根堆,由大根堆筛选出堆中最大的元素
maxHeap.offer(num);
int filteredMaxNum = maxHeap.poll();
//2.筛选后的【大根堆中的最大元素】进入小根堆
minHeap.offer(filteredMaxNum);
} else {//当数据总数为奇数时,新加入的元素,应当进入大根堆
//(注意不是直接进入大根堆,而是经小根堆筛选后取小根堆中最大元素进入大根堆)
//1.新加入的元素先入到小根堆,由小根堆筛选出堆中最小的元素
minHeap.offer(num);
int filteredMinNum = minHeap.poll();
//2.筛选后的【小根堆中的最小元素】进入大根堆
maxHeap.offer(filteredMinNum);
}
count++;
}
public Double GetMedian() {
if (count %2 == 0) {
return new Double((minHeap.peek() + maxHeap.peek())) / 2;
} else {
return new Double(minHeap.peek());
}
}
}
public class Solution {
private int count = 0;
private PriorityQueue<Integer> minHeap = new PriorityQueue<>();
// private PriorityQueue<Integer> maxHeap = new PriorityQueue<>();
private PriorityQueue<Integer> maxHeap = new PriorityQueue<Integer>(15, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
public void Insert(Integer num) {
if (count %2 == 0) {//当数据总数为偶数时,新加入的元素,应当进入小根堆
//(注意不是直接进入小根堆,而是经大根堆筛选后取大根堆中最大元素进入小根堆)
//1.新加入的元素先入到大根堆,由大根堆筛选出堆中最大的元素
maxHeap.offer(num);
int filteredMaxNum = maxHeap.poll();
//2.筛选后的【大根堆中的最大元素】进入小根堆
minHeap.offer(filteredMaxNum);
} else {//当数据总数为奇数时,新加入的元素,应当进入大根堆
//(注意不是直接进入大根堆,而是经小根堆筛选后取小根堆中最大元素进入大根堆)
//1.新加入的元素先入到小根堆,由小根堆筛选出堆中最小的元素
minHeap.offer(num);
int filteredMinNum = minHeap.poll();
//2.筛选后的【小根堆中的最小元素】进入大根堆
maxHeap.offer(filteredMinNum);
}
count++;
}
public Double GetMedian() {
if (count %2 == 0) {
return new Double((minHeap.peek() + maxHeap.peek())) / 2;
} else {
return new Double(minHeap.peek());
}
}
}
本题可以使用ArrayList实现,如果非要使用最大堆与最小堆的话:
最大堆与最小堆的实现我们可以通过使用java库自带的PriorityQueue(优先队列)来实现。最小堆就是堆头为最小的数,这样每次在使用peek()时出来的值一定是最小的值。而优先队列如果不提供Comparator的话,优先队列中元素默认按自然顺序排列,也就是数字默认是小的在队列头,所以最小堆与优先队列的排序方式是一样的,所以在设置最大堆的时候我们需要对优先队列的排序方式进行设置。
在这里我们可以看到比较的方式是通过定义compare方法:这里return o2-o1;代表是逆序,因为:
按 compare 方法的定义compare(o1,o2)
o1 < o2 负数
o1 = o2 0
o1 > o2 正数
o1 - o2 的结果与定义一致
o2 - o1的结果与定义正好相反,是逆序。
o1 < o2 负数
o1 = o2 0
o1 > o2 正数
o1 - o2 的结果与定义一致
o2 - o1的结果与定义正好相反,是逆序。
所以这样就定义了最大堆和最小堆。
对于PriorityQueue这个类参数可以为PriorityQueue()或者PriorityQueue(
int
initialCapacity, Comparator<?
super
E> comparator)。也就是像
这道题中定义的那样(匿名内部类)来定义优先队列的排列规则。
PriorityQueue拥有以下几种方法:
方法名 | 功能描述 |
---|---|
add(E e) | 添加元素 |
clear() | 清空 |
contains(Object o) | 检查是否包含当前参数元素 |
offer(E e) | 添加元素 |
peek() | 读取元素,(不删除) |
poll() | 取出元素,(删除) |
remove(Object o) | 删除指定元素 |
size() | 返回长度 |
然后接下来的看代码。