数据流中的中位数

如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。

import java.util.*;
public class Solution {

    private int count = 0;
    private PriorityQueue<Integer> minHeap = 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());
        }
    }

}
时间: 2024-08-25 13:16:11

数据流中的中位数的相关文章

剑指Offer——数据流中的中位数

题目描述: 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值.如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值. 分析: 插入排序. 代码: 1 class Solution { 2 public: 3 vector<int> v; 4 int vSize = 0; 5 void Insert(int num) { 6 v.push_back(num); 7 for(int i = vSize - 1; i

剑指:数据流中的中位数

题目描述 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值.如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值.我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数. 解法 利用大根堆存放较小的一半元素,小根堆存放较大的一半元素.维持大小堆的元素个数差不超过 1. import java.util.Comparator; import java.util.Priority

剑指OFFER 整数中1出现的次数

剑指OFFER 整数中1出现的次数 class Solution { public: int hwo_many(int n) { int count=0; while(n!=0) { if(n%10==1)count++; n/=10; } return count; } int NumberOf1Between1AndN_Solution(int n) { int count = 0; for(int i=1;i<=n;i++){ count += hwo_many(i); } return

剑指offer 数组中的逆序对

题目描述 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数P.并将P对1000000007取模的结果输出. 即输出P%1000000007 输入描述: 题目保证输入的数组中没有的相同的数字 数据范围: 对于%50的数据,size<=10^4 对于%75的数据,size<=10^5 对于%100的数据,size<=2*10^5 示例1 输入 1,2,3,4,5,6,7,0 输出 7 思路:归并排序的思路.具体参考剑指

剑指 Offer —— 数组中重复的数字

数组中的重复数字 题目描述 牛课网链接 长度为 n 的数组里,所有数字都在 0 到 n-1 的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为 7 的数组{2,3,1,0,2,5,3},那么对应的输出是重复的数字 2 或者 3.(牛课网这里弄成「那么对应的输出是第一个重复的数字 2」了) A 简单实现思路 借助外部数组 b,原数组中的数字记为外部数组的下标,外部数组的值来存储这个数字出现的次数.原数组中

剑指offer——数组中出现次数超过一半的数字(c++)

题目描述数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2.如果不存在则输出0. 思路一遍历数组是保存两个值:一个是数字中的一个数字,另一个是次数.当遍历到下一个数字的时候,如果下一个数字和之前保存的数字相等,则次数加1:如果不同,则次数减1:如果次数为零,那么我们需要保存下一个数字,并把次数设置为1.由于我们要找的数字出现的次数比其他所有数字出现的次数之和还

剑指offer | 链表中倒数第k个结点

先做做一些简单题找找手感,还有赞一个牛客的OJ,这样的提交方式很好,ACM那种对输入出处格式对于没有接触过ACM的人来说比较头疼,华为OJ那种格式描述不清楚的就更头疼了,卡在输入输出上就悲剧了,当然,输入输出也是需要了解的. 顺便吐槽一下华为SO挑战赛:题意有模糊的地方,挑战赛的题目没有区分度,作弊监管太松,判分规则未公开说明. 题目描述:输入一个链表,输出该链表中倒数第k个结点. 题目解析:设两个同步后移.相距k的指针就行,前面的指针触底,后面的指针即是倒数k个节点. 代码如下: 1 /* 2

剑指Offer 通过中序和先序遍历重建二叉树

题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回. 思路: 写一个reConstruct函数4个形参,分别记录子树前序开始结束的位置,中序开始结束的位子.每次在中序中将前序的根节点找出,讲中序分为前(左子树),后(右子树)2 个部分.递归,直到,子树的开始位置大于结束位置. AC代码: 1 /** 2

剑指offer圆圈中最后剩下的数字 和 迭代器总结

迭代器只有++ ,--,==,!=四种运算方法,不能将iter = iteration+ 1,因为迭代器是指针类型,1是整数类型,不能直接相加赋值给一个指针. 题目描述 每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此.HF作为牛客的资深元老,自然也准备了一些小游戏.其中,有个游戏是这样的:首先,让小朋友们围成一个大圈.然后,他随机指定一个数m,让编号为0的小朋友开始报数.每次喊到m-1的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下

剑指offer——数组中的逆序对

数组中的逆序对 **(不会)数据结构--小和问题 逆序对问题 原文地址:https://www.cnblogs.com/SkyeAngel/p/8978980.html