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

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;
};

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MySQL数据库(二)和java复习

一.MySQL数据库学习(二) (一).DQL查询数据 DQL&#xff08;Data Query Language&#xff09;是用于从数据库中检索数据的语言。常见的 DQL 语句包括 SELECT、FROM、WHERE、GROUP BY、HAVING 和 ORDER BY 等关键字&#xff0c;用于指定要检索的数据、数据源、过滤条件、分组方…

ROS云课三分钟外传之CoppeliaSim_Edu_V4_1_0_Ubuntu16_04

三分钟热度试一试吧&#xff0c;走过路过不要错过。 参考之前&#xff1a; 从云课五分钟到一分钟之v-rep_pro_edu_v3_6_2-CSDN博客 git clone https://gitcode.net/ZhangRelay/v-rep_pro_edu_v3_6_2_ubuntu16_04.gittar -xf v-rep_pro_edu_v3_6_2_ubuntu16_04/V-REP_PRO_EDU…

字符串常量池字符串常量的几种创建方式及其位置

从JDK7开始&#xff0c;字符串常量池被移到了堆区中&#xff0c;因此Java程序中的字符串常量对象要么在堆区的字符串常量池之中&#xff0c;要么在堆区的字符串常量池之外。为了做区分&#xff0c;下文将堆区的字符串常量池区域称为字符串常量池&#xff0c;将堆区字符串常量池…

Zabbix配置中文显示及乱码问题

页面配置为中文显示 在zabbix 5.0版本开始用户菜单更改为左侧栏显示&#xff0c;找到并点击 User Settings&#xff0c;Language 修改语言为 Chinese (zh_CN) 即可。 PS&#xff1a;一般在部署后初始配置时&#xff0c;未找到 Chinese (zh_CN) 这一项&#xff0c;修改如下&…

分享一个 .NET Core Console 项目中应用 NLog 写日志的详细例子

前言 日志在软件开发中扮演着非常重要的角色&#xff0c;通常我们用它来记录应用程序运行时发生的事件、错误信息、警告以及其他相关信息&#xff0c;帮助在调试和排查问题时更快速地定位和解决 Bug。 通过日志&#xff0c;我们可以做到&#xff1a; 故障排除和调试&#xff…

探索智慧景区的总体架构与应用

背景&#xff1a; 在旅游业快速发展的今天&#xff0c;智慧景区已成为提升景区管理水平、提高游客体验的重要手段之一。智慧景区系统的总体架构设计与应用&#xff0c;将现代信息技术与景区管理相结合&#xff0c;为景区的运营管理和游客服务提供了新的思路和解决方案。本文将…

按键精灵在Win11中弹窗出现乱码并且自带的部分系统插件不能使用的解决方法

按键精灵中出现以下问题&#xff1a; 提示信息的弹窗出现乱码&#xff1a; 系统自带的部分像 plugin. 开头的插件不能使用&#xff0c;如下&#xff1a;s Plugin.Sys.GetDateTime() screenX Plugin.GetSysInfo.GetScreenResolutionX screenY Plugin.GetSysInfo.GetScreenRe…

在Linux or Windows中如何优雅的写出对拍

在Linux or Windows中如何优雅的写出对拍 一、前言二、结论1、对拍 三、对拍详解1、什么是对拍呢&#xff1f;&#x1f9d0;2、对拍的组成部分3、输入数据生成4、对拍程序5、操作流程 四、最后 一、前言 网上的对拍程序层出不穷&#xff0c;大多Linux和Windows中的对拍程序都是…

MySQL 函数与约束

MySQL 函数与约束 文章目录 MySQL 函数与约束1 函数1.1 字符串函数1.2 数值函数1.3 日期函数1.4 流程函数 2 约束2.1 概述2.2 约束演示2.3 外键约束2.4 删除/更新行为 1 函数 函数是指一段可以直接被另一程序调用的程序或代码。 1.1 字符串函数 MySQL中内置了很多字符串函数&…

LabVIEW开发实验室超导体电流特性测试系统

本系统旨在为学校实验室提供一个基于LabVIEW的超导体电流特性测试平台&#xff0c;通过精确测量超导体在不同温度和电流条件下的电学特性&#xff0c;帮助学生和研究人员深入理解超导体的物理性质。本文将从背景、目标、工作原理、使用方法、操作流程和注意事项等方面详细介绍该…

《python程序语言设计》2018版第5章第36题改造4.17 石头 剪刀 布某一方超过2次就结束。

代码编写记录 2024.05.04 05.36.01version 换一个什么数代替剪子 我先建立一个函数judgement condition 石头3 剪子2 布1 如何构建一个循环进行的架构&#xff0c;是我们最需要的想法 循环以什么条件开始呢 是小于2个还是大于2个。 guess_num random.randint(1, 3) computer…

已解决Error || RuntimeError: size mismatch, m1: [32 x 100], m2: [500 x 10]

已解决Error || RuntimeError: size mismatch, m1: [32 x 100], m2: [500 x 10] 原创作者&#xff1a; 猫头虎 作者微信号&#xff1a; Libin9iOak 作者公众号&#xff1a; 猫头虎技术团队 更新日期&#xff1a; 2024年6月6日 博主猫头虎的技术世界 &#x1f31f; 欢迎来…

浅解Reids持久化

Reids持久化 RDB redis的存储方式&#xff1a; rdb文件都是二进制&#xff0c;很小&#xff0c;里面存的是数据 实现方式 redis-cli链接到redis服务端 使用save命令 注&#xff1a;不推荐 因为save命令是直接写到磁盘里面&#xff0c;速度特别慢&#xff0c;一般都是redis…

创新案例|创新实时零售模式,千亿时尚巨头Shein的全球扩张之路

SHEIN&#xff0c;一家估值千亿美元的快时尚电商独角兽&#xff0c;是全球增长最快的服饰平台。它通过数据和平台的双轮驱动&#xff0c;构建了全新的“实时零售”模式&#xff0c;实现了数据与商业的紧密衔接。同时&#xff0c;通过领导力和组织能力建设&#xff0c;打造了独特…

Python 全栈体系【四阶】(五十八)

第五章 深度学习 十三、自然语言处理&#xff08;NLP&#xff09; 3. 文本表示 3.1 One-hot One-hot&#xff08;独热&#xff09;编码是一种最简单的文本表示方式。如果有一个大小为V的词表&#xff0c;对于第i个词 w i w_i wi​&#xff0c;可以用一个长度为V的向量来表示…

[C++数据结构之看懂就这一篇]图(上)

&#x1f4da;博客主页&#xff1a;Zhui_Yi_&#x1f50d;&#xff1a;上期回顾&#xff1a;JAVA面向对象&#xff08;上&#xff09;❤️感谢大家点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;&#xff0c;您的三连就是我持续更新的动力❤️&#x1f387;追当今朝…

C++面向对象程序设计 - 输入输出流进一步研究

在C中&#xff0c;输入输出流&#xff08;I/O&#xff09;是一个强大的特性&#xff0c;它允许程序与各种输入/输出设备&#xff08;如键盘、显示器、文件等&#xff09;进行交互。C标准库中的<iostream>头文件定义了基本的输入输出流类&#xff0c;如std::cin&#xff0…

从河流到空气,BL340工控机助力全面环保监测网络构建

在环保监测领域&#xff0c;智能化、高效率的监测手段正逐步成为守护绿水青山的新常态。其中&#xff0c;ARMxy工业计算机BL340凭借其强大的处理能力、高度的灵活性以及广泛的兼容性&#xff0c;在水质监测站、空气质量检测、噪音污染监控等多个环保应用场景中脱颖而出&#xf…

Apache ShardingSphere实战与核心源码剖析

Apache ShardingSphere实战与核心源码剖析 1.数据库架构演变与分库分表介绍 1.1 海量数据存储问题及解决方案 如今随着互联网的发展,数据的量级也是成指数的增长,从GB到TB到PB。对数据的各种操作也是愈加的困难,传统的关系性数据库已经无法满足快速查询与插入数据的需求。…