力扣hot100:295. 数据流的中位数(两个优先队列维护中位数)

news2024/11/19 3:34:46

LeetCode:295. 数据流的中位数
在这里插入图片描述
这个题目最快的解法应该是维护中位数,每插入一个数都能快速得到一个中位数。
根据数据范围,我们应当实现一个 O ( n l o g n ) O(nlogn) O(nlogn)的算法。

1、超时—插入排序

使用数组存储,维持数组有序,当插入一个元素时使用插入排序维持数组有序,这种方式无异于使用插入排序,时间复杂度不达标。

  • 时间复杂度: O ( n 2 ) O(n^2) O(n2),由于每一个数都会被插入一次,插入一次的时间为 O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n)
    在这里插入图片描述
class MedianFinder {
public:
    MedianFinder() {}
    
    void addNum(int num) {
        nums.emplace_back(num);
        for(int i = nums.size() - 1; i >= 1; -- i){
            if(nums[i] >= nums[i - 1]) break;
            swap(nums[i], nums[i-1]);
        }
    }
    
    double findMedian() {
        int mid = nums.size() / 2;
        if(nums.size() % 2 == 1)
            return 1.0 * nums[mid];
        return 1.0 * (nums[mid] + nums[mid - 1]) / 2;
    }
private:
    vector<int> nums;
};

2、中位数为根的BST

如果我们使用二分查找,找到新加入元素的位置,是否可行呢?答案是可行的,但是使用数组存储并不能很快更新。

  • 使用高效率的树形二分查找,查找和插入效率很高,可以使用AVL、红黑树、B树等
  • 但这里要求的是能快速取得中位数,普通的树形二分查找就不行了,不能通过下标快速找到。因此只能使用数组二分查找,但是插入效率又不高

根据上面的讨论,我们发现,如果能每次插入维护的一个二叉搜索树是一个完全二叉树,根附近就是中位数,并且插入操作只需要 O ( l o g n ) O(logn) O(logn)的时间,那就太好了。

这样我们就可以思考,能不能实现这样的数据结构:

  • 对于任何一段区间,满足根是中位数,且左子树小于根,根小于右子树的一个二叉搜索树
    • 我们规定偶数情况下,两个数小者作为根。如下图:
      在这里插入图片描述

如果能实现这样的数据结构,就刚好和题目要求实现“数据结构”这一说法匹配了!
(我感觉是能实现的,但是时间问题,我就先不写了,有兴趣的同学可以自行研究)

3、优先队列

维护两个优先队列,一个存储比中位数小于的最大堆,一个存储比中位数大的最小堆(包括等于的,即最小堆里面的元素可能会比最大堆多一个)。那么我们就将数分为了两堆,很显然中位数能通过某种方式从两个优先队列队头取到。

并且很显然,维护这两个堆也很容易,当需要插入一个数时,我们只需要比较两个堆队头就可以选择插入的堆。并且为了维持两个堆队头是中位数

  • 当元素数为偶数时,插入一个元素,如果插入到左边,则最后中位数会出现在左边,我们将其放入右边。如果插入到右边则直接结束
  • 当元素数为奇数,插入一个元素,如果插入到左边则结束,如果插入到右边则右边多一个需要放一个放到左边。
  • 不管怎么放,根据优先队列的性质,队头都是最值,即根据中位数将区间分为两段,通过优先队列快速进行维护,左右的边界值。

时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn),一次插入时间复杂度 O ( l o g n ) O(logn) O(logn)
空间复杂度: O ( n ) O(n) O(n)

class MedianFinder {
public:
    MedianFinder() {left.push(-0x3f3f3f3f);right.push(0x3f3f3f3f);}
    
    void addNum(int num) {
        ++n;
        //先插入
        if(num >= right.top()){
            right.push(num);
        }else left.push(num);
        //再移动
        if(left.size() > right.size()){
            right.push(left.top());
            left.pop();
        }else{
            if(right.size() == left.size() + 2){
                left.push(right.top());
                right.pop();
            }
        }
        return;
    }
    
    double findMedian() {
        if(n & 1){//n & 1 == 1 即奇数
            return right.top();
        }
        return (left.top() + right.top()) / 2.0;
    }
private:
    priority_queue<int, vector<int>, less<int>> left;//左区间
    priority_queue<int, vector<int>, greater<int>> right;//右区间
    int n = 0;
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1799288.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

pyqt5 tablewidget实现excel拖曳填充

代码主要涉及鼠标事件和绘图&#xff0c;selectionModel&#xff0c;selectedIndexes。 import sys from PyQt5.QtCore import QPoint, Qt, QCoreApplication, pyqtSlot from PyQt5.QtGui import QBrush, QPixmap, QColor, QPainter,QIcon,QPolygon from PyQt5.QtWidgets imp…

GPT-4o:突出优势 和 应用场景

还是大剑师兰特&#xff1a;曾是美国某知名大学计算机专业研究生&#xff0c;现为航空航海领域高级前端工程师&#xff1b;CSDN知名博主&#xff0c;GIS领域优质创作者&#xff0c;深耕openlayers、leaflet、mapbox、cesium&#xff0c;canvas&#xff0c;webgl&#xff0c;ech…

NeMo Guardrails 大模型安全防护:这个框架牛逼,不会像强化学习 指令对齐限制灵活性死板回答,也不会像提示词约束容易被遗忘和清理

NeMo Guardrails 大模型安全防护&#xff1a;这个框架牛逼&#xff0c;不会像强化学习 指令对齐限制灵活性死板回答&#xff0c;也不会像提示词约束容易被遗忘和清理 提出背景对比传统方法结构图底层原理1. 对话管理运行时&#xff08;DM-like runtime&#xff09;2. 思维链&am…

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

​​​​​​​​​​ 一、思路 我们将所有数据平分成两份&#xff0c;前面那一部分用小堆来存&#xff0c;后面的部分用大堆来存&#xff0c;这样我们就能立刻拿到中间位置的值。 如果是奇数个数字&#xff0c;那么我们就将把中间值放在前面的大堆里&#xff0c;所以会有两种…

SAP ABAP 创建表结构 SE11

目录 一&#xff0c;创建表 &#xff1a;T-code:SE11 二&#xff0c;编辑内容&#xff1a; 1&#xff0c;内容说明&#xff1a;必填项&#xff0c;属性&#xff1a;锁定不可更改 2&#xff0c;出荷と更新 &#xff13;&#xff0c;項目 A&#xff1a;表的第一个项目必须是…

Flink中因java的泛型擦除导致的报错及解决

【报错】 Exception in thread "main" org.apache.flink.api.common.functions.InvalidTypesException: The return type of function Custom Source could not be determined automatically, due to type erasure. You can give type information hints by using th…

计算机网络面试基础(一)

文章目录 一、HTTP基本概念1.HTTP是什么&#xff1f;2.HTTP 常见的状态码有哪些&#xff1f;3.http常见字段 二、GET和POST1.get和post有什么区别 三、HTTP缓存技术1.HTTP 缓存有哪些实现方式&#xff1f;2.什么是强制缓存&#xff1f;3.什么是协商缓存&#xff1f;(不太懂) 四…

linux嵌入式设备测试wifi信号强度方法

首先我们要清楚设备具体链接在哪个wifi热点上 执行&#xff1a;nmcli dev wifi list rootubuntu:/home/ubuntu# nmcli dev wifi list IN-USE BSSID SSID MODE CHAN RATE SIGNAL BARS > * 14:EB:08:51:7D:20 wifi22222_5G Infr…

【96】write combine机制介绍

前言 这篇文章主要介绍了write combine的机制 一、write combine的试验 1.系统配置 &#xff08;1&#xff09;、CPU&#xff1a;11th Gen Intel(R) Core(TM) i7-11700 2.50GHz &#xff08;2&#xff09;、GPU&#xff1a;XX &#xff08;3&#xff09;、link status&am…

如何有效提问?

有效提问&#xff1a;正确地向别人提问是一种艺术&#xff0c;可以帮助你获得清晰、有用的答案。 明确表达问题&#xff1a;确保你的问题清晰明了&#xff0c;避免含糊不清或模棱两可的语言。这可以帮助对方更好地理解你的问题&#xff0c;并给出准确的答复。 尊重对方&#x…

[第五空间 2021]WebFTP、[HCTF 2018]Warmup

目录 [第五空间 2021]WebFTP ​[SWPUCTF 2021 新生赛]Do_you_know_http [NCTF 2018]签到题 [HNCTF 2022 Week1]What is Web [HNCTF 2022 Week1]Interesting_http [HCTF 2018]Warmup [第五空间 2021]WebFTP 使用dirsearch扫描&#xff0c;发现有git泄露 使用GitHack克隆目…

HBuilderX编写APP一、获取token

一、新建项目 二、从onenet获取key.js 1、下载之后的压缩包&#xff0c;解压 2、关键就是找到key.js 3、将这个key.js复制到刚才的目录下面去 4、这个key.js文件就是生成token的代码 5、只要调用createCommonToken(params)这个函数&#xff0c;就可以实现生成token了 其中on…

小米开放式耳机怎么样?倍思、西圣、小米开放式耳机测评比较!

作为一名热衷于分享真实体验的博主&#xff0c;我在过去两年开始接触开放式耳机&#xff0c;并因此受到许多朋友的咨询&#xff0c;询问哪款开放式耳机更加出色。为了找出最佳的开放式耳机&#xff0c;我进行了深入的调查和实地测试。我发现高价并不总是代表高质量&#xff0c;…

【全开源】Java共享茶室棋牌室无人系统支持微信小程序+微信公众号

打造智能化休闲新体验 一、引言&#xff1a;智能化休闲时代的来临 随着科技的飞速发展&#xff0c;智能化、无人化服务逐渐渗透到我们生活的各个领域。在休闲娱乐行业&#xff0c;共享茶室棋牌室无人系统源码的出现&#xff0c;不仅革新了传统的休闲方式&#xff0c;更为消费…

嵌入式移植jpeglib--Linux交叉编译ARM平台

一 、交叉编译jpeg库 1.下载源码tar.gz 2. 源码目录下执行 jpeglib配置文件 ./configure CCarm-none-linux-gnueabihf-gcc LDarm-none-linux-gnueabihf-ld --prefix/work/jpeg_arm_lib --exec-prefix/work/jpeg_arm_lib --enable-shared --enable-static --hostarm-none-linu…

高考试卷押运车视频监控解决方案

一、引言 高考作为我国教育领域的重要事件&#xff0c;其公正、公平和安全性一直备受社会关注。试卷押运作为高考的重要环节&#xff0c;其安全性直接关系到高考的顺利进行和考生的切身利益。因此&#xff0c;对高考试卷押运车实施视频监控解决方案&#xff0c;对于确保试卷安…

Asp .Net Core 系列:详解鉴权(身份验证)以及实现 Cookie、JWT、自定义三种鉴权 (含源码解析)

什么是鉴权&#xff08;身份验证&#xff09;&#xff1f; https://learn.microsoft.com/zh-cn/aspnet/core/security/authentication/?viewaspnetcore-8.0 定义 鉴权&#xff0c;又称身份验证&#xff0c;是确定用户身份的过程。它验证用户提供的凭据&#xff08;如用户名和…

短视频直播教学课程小程序的作用是什么

只要短视频/直播做的好&#xff0c;营收通常都不在话下&#xff0c;近些年&#xff0c;线上自媒体行业热度非常高&#xff0c;每条细分赛道都有着博主/账号&#xff0c;其各种优势条件下也吸引着其他普通人冲入。 然无论老玩家还是新玩家&#xff0c;面对平台不断变化的规则和…

【第四节】C/C++数据结构之树与二叉树

目录 一、基本概念与术语 二、树的ADT 三、二叉树的定义和术语 四、平衡二叉树 4.1 解释 4.2 相关经典操作 4.3 代码展示 一、基本概念与术语 树(Tree)是由一个或多个结点组成的有限集合T。其中: 1 有一个特定的结点&#xff0c;称为该树的根(root)结点&#xff1b; 2 …

python-df的合并与Matplotlib绘图

1 数据连接 concat merge join &#xff08;append 作为了解&#xff09; append 竖直方向追加&#xff0c; 在最新的pandas版本中已经被删除掉了&#xff0c; 这里推荐使用concat 1.1 pd.concat 两张表&#xff0c; 通过行名、列名对齐进行连接 import pandas as pd df1 …