当前位置: 首页 > article >正文

算法通关村-----数据流的中位数

数据流的中位数

问题描述

中位数是有序整数列表中的中间值。如果列表的大小是偶数,则没有中间值,中位数是两个中间值的平均值。

例如 arr = [2,3,4] 的中位数是 3 。
例如 arr = [2,3] 的中位数是 (2 + 3) / 2 = 2.5 。
实现 MedianFinder 类:

MedianFinder() 初始化 MedianFinder 对象。

void addNum(int num) 将数据流中的整数 num 添加到数据结构中。

double findMedian() 返回到目前为止所有元素的中位数。与实际答案相差 10-5 以内的答案将被接受。

详见leetcode295

问题分析

查大用小,查小用大,查中间则需要两个堆,一个最大堆,一个最小堆,遍历元素,当最小堆为空或者当前元素大于最小堆堆顶元素时,放入最小堆,否则放入最大堆,当两个堆的元素数量相差大于1时,数量多的堆移除堆顶元素,放入另一个堆。如此,遍历结束后,小顶堆中存放着全部元素中较大的一半,大顶堆中存储着全部元素中较小的一半。中位数或为两个堆顶元素的均值,或者为数量多的堆的堆顶元素

图示过程

以添加[1,2,3,4,5]为例,展示两个堆的变化过程,初始时,两个堆均为空。
1.添加1,此时minHeap为空,添加到minHeap中
1
2.添加2,2>minHeap的堆顶元素1,添加到minHeap中,此时minHeap中的元素数量为2,maxHeap中的元素数量为0,数量差大于1,所以minHeap移除堆顶元素,放入maxHeap中
2
3.添加3,3>minHeap的堆顶元素2,添加到minHeap中,此时minHeap中的元素数量为2,maxHeap中的元素数量为1,数量差等于1,无需再操作
3
4.添加4,4>minHeap的堆顶元素2,添加到minHeap中,此时minHeap中的元素数量为3,maxHeap中的元素数量为1,数量差大于1,所以minHeap移除堆顶元素,放入maxHeap中
4
5.添加5,5>minHeap的堆顶元素3,添加到minHeap中,此时minHeap中的元素数量为3,maxHeap中的元素数量为2,数量差等于1,无需再操作
5
此时,两个堆的元素数量相差1,中位数为两个堆的堆顶元素均值

代码实现

class MedianFinder {
    PriorityQueue<Integer> minHeap;
    PriorityQueue<Integer> maxHeap;

    public MedianFinder() {
        minHeap = new PriorityQueue<Integer>((a, b) -> a - b);
        maxHeap = new PriorityQueue<Integer>((a, b) -> b - a);
    }
    
    public void addNum(int num) {
        if (minHeap.isEmpty() || num > minHeap.peek()) {
            minHeap.offer(num);
            if (minHeap.size() - maxHeap.size() > 1) {
                maxHeap.offer(minHeap.poll());
            }
        } else {
            maxHeap.offer(num);
            if (maxHeap.size() - minHeap.size() > 1) {
                minHeap.offer(maxHeap.poll());
            }
        }
    }
    
    public double findMedian() {
        if (minHeap.size() == maxHeap.size()) {
            return (minHeap.peek() + maxHeap.peek()) / 2.0;
        }else{
            return minHeap.size()>maxHeap.size()? minHeap.peek() : maxHeap.peek();
        }
    }
}

http://www.kler.cn/a/148483.html

相关文章:

  • LeetCode【0035】搜索插入位置
  • 陪诊问诊APP开发实战:基于互联网医院系统源码的搭建详解
  • Elasticsearch 实战应用:高效搜索与数据分析
  • 《深度解析 C++中的弱引用(weak reference):打破循环依赖的利器》
  • 使用jmeter查询项目数据库信息,保存至本地txt或excel文件1108
  • DOM 规范 — MutationObserver 接口
  • 企业源代码防泄密的有什么痛点及难点?
  • 安装MySQL搭建论坛
  • 通过测试驱动开发(TDD)的方式开发Web项目
  • Rust UI开发(一):使用iced构建UI时,如何在界面显示中文字符
  • 项目问题总结
  • 华为OD机试真题-整数对最小和-2023年OD统一考试(C卷)
  • 简要介绍Spring原生框架与Spring是轻量级框架的原因
  • 原生DOM事件、react16、17和Vue合成事件
  • Git控制指令
  • C语言枚举的作用是什么?
  • Java中类的类型判断技巧以及没有无参构造函数时的应对策略。isInstance()方法解析
  • PTA:编程实现strncpy函数功能(C语言)
  • Docker笔记-Docker搭建最新版zabbix服务端(2023-07-31)
  • Android开源框架--Dagger2详解
  • PCL 计算点云图中任意两点的欧式距离
  • Drool 7 SpreadSheet Decision Template 笔记
  • SpringBoot 项目中获取 Request 的四种方法
  • [Linux] Linux入门必备的基本指令(不全你打我)
  • 外观设计模式
  • 【双指针】三数之和