[剑指offer] 数据流中的中位数

简介: 本文首发于我的个人博客:尾尾部落题目描述如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。

本文首发于我的个人博客:尾尾部落

题目描述

如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。

解题思路

我们可以将数据排序后分为两部分,左边部分的数据总是比右边的数据小。那么,我们就可以用最大堆和最小堆来装载这些数据:

  • 最大堆装左边的数据,取出堆顶(最大的数)的时间复杂度是O(1)
  • 最小堆装右边的数据,同样,取出堆顶(最小的数)的时间复杂度是O(1)

从数据流中拿到一个数后,先按顺序插入堆中:如果左边的最大堆是否为空或者该数小于等于最大堆顶的数,则把它插入最大堆,否则插入最小堆。然后,我们要保证左边的最大堆的size等于右边的最小堆的size或者最大堆的size比最小堆的size大1。
要获取中位数的话,直接判断最大堆和最小堆的size,如果相等,则分别取出两个堆的堆顶除以2得到中位数,不然,就是最大堆的size要比最小堆的size大,这时直接取出最大堆的堆顶就是我们要的中位数。

参考代码

import java.util.PriorityQueue;
import java.util.Comparator;
public class Solution {
    // 最小堆(右)
    private PriorityQueue<Integer> rHeap = new PriorityQueue<>(); 
    // 最大堆(左)
    private PriorityQueue<Integer> lHeap = new PriorityQueue<Integer>(15, new Comparator<Integer>() {
            public int compare(Integer o1, Integer o2) {
                return o2 - o1;
            }
        });
    // 保证lHeap.size()>=rHeap.size()
    public void Insert(Integer num) {
        // 先按大小插入,再调整
        if(lHeap.isEmpty() || num <= lHeap.peek())
            lHeap.offer(num);
        else
            rHeap.offer(num);
        
        if(lHeap.size() < rHeap.size()){
            lHeap.offer(rHeap.peek());
            rHeap.poll();
        }else if(lHeap.size() - rHeap.size() == 2){
            rHeap.offer(lHeap.peek());
            lHeap.poll();
        }
    }
    public Double GetMedian() {
        if(lHeap.size() > rHeap.size())
            return new Double(lHeap.peek());
        else
            return new Double(lHeap.peek() + rHeap.peek())/2;
    }
}
目录
相关文章
|
人工智能 Linux API
LangChain开发环境准备-AI大模型私有部署的技术指南
今天开始小智将开启系列AI应用开发课程,主要基于LangChain框架基于实战项目手把手教大家如何将AI这一新时代的基础设施应用到自己开发应用中来。欢迎大家持续关注
983 0
|
监控 Java Shell
基于python+uiautomator2,2020.12月最新库的使用方法,更新watcher使用方法(三)
WatchContext,目前的这个watch_context是用threading启动的,每2s检查一次 目前还只有click这一种触发操作
1665 0
|
6月前
|
API
掌握 HTTP 请求的艺术:理解 cURL GET 语法
掌握 cURL GET 请求的语法和使用方法是 Web 开发和测试中的基本技能。通过灵活运用 cURL 提供的各种选项,可以高效地与 API 进行交互、调试网络请求,并自动化日常任务。希望本文能帮助读者更好地理解和使用 cURL,提高工作效率和代码质量。
342 7
|
7月前
|
机器学习/深度学习 人工智能 自然语言处理
魔搭社区模型速递(1.19-2.15)
魔搭ModelScope本期社区进展:6205个模型,823个数据集,333个创新应用, 26篇内容。
436 2
魔搭社区模型速递(1.19-2.15)
|
5月前
|
算法 物联网 Swift
Qwen3 X ModelScope工具链: 飞速训练 + 全面评测
Qwen于近日发布了Qwen3系列模型,包含了各个不同规格的Dense模型和MoE模型。开源版本中,Dense模型基本沿用了之前的模型结构,差别之处在于对于Q和K两个tensor增加了RMSNorm;MoE模型去掉了公共Expert,其他结构基本与前一致。在模型大小上,涵盖了从0.6B到32B(Dense)和235B(MoE)不同的尺寸。
688 15
|
存储 Unix Linux
Linux中如何写一个倒计时的脚本
由于项目需要编写一个脚本中倒计时的功能,思路总体是一个for循环中echo. 但是如何做到优雅还需要使用tput来打磨。
328 1
|
人工智能 算法
从RLHF到DPO再到TDPO,大模型对齐算法已经是token-level
【7月更文挑战第1天】在AI领域的语言模型对齐研究中,新提出的TDPO算法实现了Token-level的直接优化。不同于以往在答案级别评估的方法,TDPO利用前向KL散度和Bradley-Terry模型,直接在生成过程的Token层面上调整对齐,提高微调精度和多样性。实验显示,TDPO优于DPO和RLHF,在某些任务上表现出色,但也面临计算资源需求高、处理复杂任务时局限性等问题,需要进一步验证和改进。[论文链接](https://arxiv.org/abs/2404.11999)
407 8
|
SQL 关系型数据库 MySQL
|
Go 开发工具 iOS开发
mac go环境的安装和卸载,环境变量配置
go环境的安装和卸载, 有时已经安装过,需要对go版本进行升级. 所以我们需要先卸载, 然后在安装
1118 0
mac go环境的安装和卸载,环境变量配置