题目描述:
如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。
题解:
因为数据流是动态的,所以我们需要动态的调整整个数据序列,以及需要找出其中位数。我们知道,如果元素个数为偶数且序列有序,中位数为最中间两数之和。如果是奇数,就为最中间的那个数。
所以我们采用大堆和小堆,让元素在堆里排序。用大堆来存放排序后的前半部分元素,用小堆来存放后半部分数字。如果元素个数为偶数,返回(大堆顶顶元素 + 小堆队形元素)/ 2。如果元素个数为奇数,返回 大堆堆顶元素。
如果再次添加一个数字,需要取这个序列的中位数,需要看当前元素个数为奇数还是偶数。
- 如果是奇数,先将其与小堆堆顶元素比较
(1)如果 num 大于当前小堆堆顶元素,则判定 num 是属于后半部分的数字,所以将其加进小堆。然后调整,将小堆堆顶元素加进大堆中,此时大堆的堆顶元素就是中位数。
(2)如果num 小于当前小堆的堆顶元素,则直接添加进大堆,此时大堆的堆顶元素就是中位数。
- 如果是偶数,同理,先和大堆的堆顶元素进行比较
(1)如果 num 小于当前大堆堆顶元素,则判定 num 是属于后前部分的数字,所以将其加进大堆。然后调整,将大堆堆顶元素加进小堆中。
(2)如果num 大于当前大堆的堆顶元素,则直接添加进大堆。
中位数为(大堆顶顶元素 + 小堆队形元素)/ 2 。
import java.util.Comparator;
import java.util.PriorityQueue;
public class Solution {