首页 > 其他分享 >大小堆运用巧解数据流的中位数

大小堆运用巧解数据流的中位数

时间:2024-08-19 22:55:36浏览次数:4  
标签:right top 中位数 push num 巧解 数据流 size left

​​​​​​​​​​在这里插入图片描述

一、思路

我们将所有数据平分成两份,前面那一部分用小堆来存,后面的部分用大堆来存,这样我们就能立刻拿到中间位置的值。
在这里插入图片描述

如果是奇数个数字,那么我们就将把中间值放在前面的大堆里,所以会有两种情况,我们将大堆成为left,小堆成为right。

  • 当数据量是偶数的时候,left.size() == right.size(),这时候中间值就是left.top()
  • 当数据量是奇数的时候,这时候的left.size() == right.size() + 1,这时候的中位数就是 (left.size() + right.size()) / 2.0

二、如何存储数据?

因为左边是大堆,右边是小堆,这时候会有两个大类的情况

第一种 left.size() = right.size()

这时候,由于左边的数据都是会比left.top()小,右边的数据都会比左边的数据大,所以我们可以根据这个条件开进行讨论
假如要插入的数据是num

  • 如果left.empty() || num <= left.top() ,这时候就直接将num插进左边的大堆中
  • 如果num > left.top(),这时候应该要插进右边的小堆,但由于我们规定只能两边数据相等,或者右边的比左边的数据量多一个,所以这时候我们要:
    1.先把数据插入进right,
    2.然后拿到right.top(),因为这是right的最小值
    3.将right.top() 插进 left.top()中,然后再让right.pop()

第二种 left.size() > right.size()

  • 如果num > left.top() ,直接把num插进right中
  • 如果num <= left.top(), 这时候由于left的大小比right多1,所以我们可以参考第一种情况那样
  1. 把数据插进left
  2. 将left.top() 插入到 right中
  3. left.pop()

三、代码

class MedianFinder {
public:
    priority_queue<int> left;
    priority_queue<int, vector<int>, greater<int>> right;
    MedianFinder() {

    }
    
    void addNum(int num) {
        if(left.size() == right.size())
        {
            if(left.empty() || left.top() >= num) 
            {
            	left.push(num);
            }
            else if(left.top() < num)   
            {
                right.push(num);
                int y = right.top();
                right.pop();
                left.push(y);
            }
        }
        else
        {
            if(left.top() >= num)   
            {
                left.push(num);
                right.push(left.top());
                left.pop();
            }
            else 
            {
                right.push(num);
            }
        }
        
    }
    
    double findMedian() {
        if(left.size() == right.size()) return (left.top() + right.top()) / 2.0;
        else return left.top();
    }
};

标签:right,top,中位数,push,num,巧解,数据流,size,left
From: https://blog.csdn.net/2403_86785171/article/details/141336849

相关文章

  • 记一次完整的SpringBatch批处理数据流程
    记一次完整的SpringBatch批处理数据流程需求从400多行数据的Excel表格中批量读取数据,根据读取的数据再去调用api,拿到关键返回数据后整合写入新Excel文件。excel表格仅第一列数据手机号为有效数据,需要读取。通过手机号调用api,获取手机号对应的学生信息-学院,班级,姓名,手机号......
  • Kettle PDI小白新手/进阶/必备 大数据基础之一数据清洗(ETL)基础进阶总结 1.6万字长文
    Kettle是一个开源的数据集成工具,主要用于ETL(抽取、转换、加载)过程。它的全名是PentahoDataIntegration(PDI),而Kettle是其早期的名字,Kettle在2006年被Pentaho收购后,正式更名为PentahoDataIntegration(PDI),因此现在更常被称为PDI。PDI仍然是Pentaho产品套件中的一个重要......
  • python 计算中位数、四分位数、最大值、最小值等
    还是之前的那一堆csv数,主要算每列的中位数、四分位数、最大值、最小值等我在这里做个笔记,方便下次用的时候直接粘过来用#!usr/bin/envpython#-*-coding:utf-8-*-"""@author:Suyue@file:vilolinpic.py@time:2024/08/13@desc:"""importpandasaspddf=pd.rea......
  • 【JavaEE初阶】文件内容的读写—数据流
    ......
  • Day 2:3107 使数组中位数等于k的最少操作数
    3107使数组中位数等于k的最少操作数1.题目描述2.解题思路3.代码实现1.题目描述3107使数组中位数等于k的最少操作数2.解题思路(1)对nums数组从小到大排序,注意到mid=nums.size()/2位置处的值为中位数;(2)判断中位数与k的大小关系:若中位数大于k,则向左依次......
  • 打造高效存储与访问体验:NFS共享携手Nginx负载均衡,赋能企业级数据流通与性能优化
     作者简介:我是团团儿,是一名专注于云计算领域的专业创作者,感谢大家的关注 座右铭:   云端筑梦,数据为翼,探索无限可能,引领云计算新纪元 个人主页:团团-CSDN博客前言:随着业务的增长,公司需要更多的服务器来支持用户访问和应用程序的运行。NFS共享可以解决文件存储的问题,而n......
  • 中位数
    题目题解1.首先我们可以想到,既然需要输出(n+1)/2次,所以我们可以每次排序一下,并在其为奇数的时候输出它们中间的数。#include<iostream>#include<algorithm>#include<queue>usingnamespacestd;intN;inta[100001];intmain(){ cin>>N; for(inti=0;i<......
  • CF1993D-二分+dp处理中位数
    CF1993D-二分+dp处理中位数大致题意给定两个正整数n和k以及另一个由n个整数组成的数组a。在一次操作中,可以选择a的任意一个大小为k的子数组,然后将其从数组中删除,而不改变其他元素的顺序。更正式地说,假设$(l,r)$是对子数组\(a_l,a_{l+1},…,a_r\)的操作,使得\(r......
  • SQL进阶技巧:Hive如何巧解和差计算的递归问题?【应用案例2】
    目录0问题描述1数据准备2问题分析3小结 0问题描述有如下数据:反应了每月的页面浏览量现需要按照如下规则计算每月的累计阅读量,具体计算规则如下:最终结果如下:1数据准备withdataas(select'2024-01'asmonth,2aspvunionallselect'2024-02'asm......
  • net core 获了取post数据流
    1、可以实例化的通过参数获取[HttpPost]publicIActionResultPost([FromBody]MyModelmodel){//在这里你可以使用model中的数据returnOk(model);}当你发送一个POST请求到这个控制器动作时,ASP.NETCore将自动将请求体中的JSON数据绑定到M......