剑指offer 42. 数据流中的中位数

简介: 剑指offer 42. 数据流中的中位数

题目描述

如何得到一个数据流中的中位数

如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。

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


数据范围

数据流中读入的数据总数 [1,1000]

输入:1, 2, 3, 4
输出:1,1.5,2,2.5
解释:每当数据流读入一个数据,就进行一次判断并输出当前的中位数。


方法一:堆 O(nlogn)


我们可以利用大根堆和小根堆的性质,创建这样两个堆,用大根堆去存储中位数往左的数,用小根堆去存储中位数往右的数。这两个堆一定满足以下两个条件(大根堆中的所有数都要小于等于小根堆中的数):


如果数的个数 n 为奇数,则大根堆需要存 n/2 + 1 个数,小根堆需要存 n/2 个数。

如果数的个数 n 为偶数,则大根堆需要存 n/2 个数,小根堆需要存 n/2 个数。


放入元素 x :


如果两个堆元素数量相同,则先把 x 放入右边的小根堆,再从小根堆堆顶拿出一个元素放到左边的大根堆,这样保证左边堆的数值都小于右边堆的数值。

如果两个堆元素数量不同即左边堆的数大于右边堆的数,则先把 x 放入左边的大根堆,再从大根堆堆顶拿出一个元素放到右边的小根堆,这样保证右边堆的数值都大于左边堆的数值。拿出中位数:


如果两个堆元素数量不同,则返回左边堆的堆顶。因为左边堆是大根堆,所以堆顶是该堆中值最大的,由于两个堆元素数量不同即元素总数是奇数,故中位数是取中间的值。为了能快速取出中位数,大根堆的数量就要比小根堆的数量大 1 ,这多出的那个 1 就是中位数。

假设要求 [1,2,3,4,5] 的中位数,则左边的大根堆中存 [1,2,3] ,右边的小根堆中存 [4,5] ,而大根堆堆顶 3 就是中位数。

如果两个堆元素数量相同,则返回左边堆的堆顶和右边堆的堆顶的平均值。同理,由于两个堆元素数量相同,则中位数是中间两个数的平均数,所以将大根堆堆顶与小根堆堆顶取平均值。

假设要求 [1,2,3,4] 的中位数,则左边的大根堆中存 [1,2] ,右边的小根堆存 [3,4] ,而平均数就是大根堆的堆顶 2 和小根堆的堆顶 3 求平均值得 2.5 。

class Solution {
public:
    priority_queue<int, vector<int>> maxHeap;    //大根堆
    priority_queue<int, vector<int>, greater<int>> minHeap;   //小根堆
    void insert(int num) {
        if (maxHeap.size() == minHeap.size())
        {
            minHeap.push(num);
            maxHeap.push(minHeap.top());
            minHeap.pop();
        }
        else
        {
            maxHeap.push(num);
            minHeap.push(maxHeap.top());
            maxHeap.pop();
        }
    }
    double getMedian() {
        if (maxHeap.size() == minHeap.size())
            return (maxHeap.top() + minHeap.top()) * 1.0 / 2;
        else
            return maxHeap.top() * 1.0;
    }
};


欢迎大家在评论区交流~

目录
相关文章
|
存储 搜索推荐 安全
Onlyfans如何使用搜索功能?Onlyfans如何搜索博主?如何在OnlyFans搜索HongkongDoll
本文是一份全面的指南,旨在帮助读者了解如何在OnlyFans平台上有效使用搜索功能,尤其是如何找到特定的博主,比如HongkongDoll。我们深入探讨了OnlyFans的搜索机制,包括其对用户隐私的重视以及因此带来的搜索限制。文章详细介绍了三种主要的搜索方法:使用OnlyFans的官方搜索服务、通过社交媒体链接进行跳转、以及利用第三方搜索引擎如OnlySearch。
|
移动开发 Java Android开发
构建高效Android应用:Kotlin协程的实践之路
【2月更文挑战第31天】 在移动开发领域,性能优化和流畅的用户体验一直是开发者追求的目标。随着Kotlin语言的流行,其异步编程解决方案——协程(Coroutines),为Android应用带来了革命性的并发处理能力。本文将深入探讨Kotlin协程的核心概念、设计原理以及在Android应用中的实际应用案例,旨在帮助开发者掌握这一强大的工具,从而提升应用的性能和响应能力。
|
存储 SQL 监控
22 PostgreSQL 监控3PostgreSQL 性能快照和图形化分析工具 pg_stats_info 的使用|学习笔记
快速学习22 PostgreSQL 监控3PostgreSQL 性能快照和图形化分析工具 pg_stats_info 的使用
22 PostgreSQL 监控3PostgreSQL 性能快照和图形化分析工具 pg_stats_info 的使用|学习笔记
|
Cloud Native Go 开发工具
不改一行代码轻松玩转 Go 应用微服务治理
为了更好的进行 Go 应用微服务治理,提高研发效率和系统稳定性,本文将介绍 MSE 微服务治理方案,无需修改业务代码,实现治理能力。
20146 97
|
Java 数据安全/隐私保护
Neo4j【付诸实践 01】SpringBoot集成报错org.neo4j.driver.exceptions.ClientException:服务器不支持此驱动程序支持的任何协议版本(解决+源代码)
Neo4j【付诸实践 01】SpringBoot集成报错org.neo4j.driver.exceptions.ClientException:服务器不支持此驱动程序支持的任何协议版本(解决+源代码)
795 1
|
NoSQL Linux Redis
Redis内存分析工具RDR
Redis内存分析工具RDR
2039 1
域名备案
阿里云账号实名认证与域名实名认证可以不一致,备案针对域名实名认证。一个阿里云账号只能有一个备案主体,且主体只能在一个账号上。域名、服务器和备案主体所在账号可以不同,但可通过服务器账号生成备案服务码授权给备案主体账号进行备案。
669 3
|
消息中间件 安全 Java
学习认识Spring Boot Starter
在SpringBoot项目中,经常能够在pom文件中看到以spring-boot-starter-xx或xx-spring-boot-starter命名的一些依赖。例如:spring-boot-starter-web、spring-boot-starter-security、spring-boot-starter-data-jpa、mybatis-spring-boot-starter等等。
414 4
|
监控 前端开发 JavaScript