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

思路及解答排序列表法

每次获取中位数前进行排序

java

import java.util.ArrayList; import java.util.Collections; import java.util.List; public class MedianFinder1 { private List<Integer> data; public MedianFinder1() { data = new ArrayList<>(); } // 插入数字到数据流 public void Insert(Integer num) { data.add(num); // 每次插入后排序,保持列表有序 Collections.sort(data); } // 获取当前数据流的中位数 public Double GetMedian() { int size = data.size(); if (size == 0) return 0.0; if (size % 2 == 1) { // 奇数个元素,返回中间值 return (double) data.get(size / 2); } else { // 偶数个元素,返回中间两个数的平均值 int mid = size / 2; return (data.get(mid - 1) + data.get(mid)) / 2.0; } } }
  • 插入操作:每次插入需要排序,时间复杂度O(n log n)
  • 获取中位数:直接通过索引访问,时间复杂度O(1)
  • 空间复杂度:O(n),需要存储所有数据

插入排序法

在方法一基础上优化,在插入时就找到正确位置,避免每次都完整排序。同时利用二分查找找到插入位置,减少排序开销

java

import java.util.ArrayList; import java.util.List; public class MedianFinder2 { private List<Integer> data; public MedianFinder2() { data = new ArrayList<>(); } public void Insert(Integer num) { // 使用二分查找找到合适的插入位置 int left = 0, right = data.size() - 1; while (left <= right) { int mid = left + (right - left) / 2; if (data.get(mid) < num) { left = mid + 1; } else { right = mid - 1; } } // 在找到的位置插入元素 data.add(left, num); } public Double GetMedian() { int size = data.size(); if (size == 0) return 0.0; if (size % 2 == 1) { return (double) data.get(size / 2); } else { int mid = size / 2; return (data.get(mid - 1) + data.get(mid)) / 2.0; } } }
  • 插入操作:二分查找O(log n) + 插入操作O(n) = O(n)
  • 获取中位数:O(1),通过索引直接访问
  • 优化效果:比方法一有明显提升,特别适合部分有序的数据

双堆法

是最高效的解法,利用大顶堆和小顶堆的特性来动态维护中位数,使用大顶堆存较小一半,小顶堆存较大一半

⽤⼀个数字来不断统计数据流中的个数,并且创建⼀个最⼤堆,⼀个最⼩堆

  • 如果插⼊的数字的个数是奇数的时候,让最⼩堆⾥⾯的元素个数⽐最⼤堆的个数多 1 ,这样⼀来中位数就是⼩顶堆的堆顶
  • 如果插⼊的数字的个数是偶数的时候,两个堆的元素保持⼀样多,中位数就是两个堆的堆顶的元素相加除以2 。

java

public class Solution { private int count = 0; private PriorityQueue<Integer> min = new PriorityQueue<Integer>(); private PriorityQueue<Integer> max = new PriorityQueue<Integer>(new Comparator<Integer>() { public int compare(Integer o1, Integer o2) { return o2 - o1; } }); public void Insert(Integer num) { count++; if (count % 2 == 1) { // 奇数的时候,需要最⼩堆的元素⽐最⼤堆的元素多⼀个。 // 先放到最⼤堆⾥⾯,然后弹出最⼤的 max.offer(num); // 把最⼤的放进最⼩堆 min.offer(max.poll()); } else { // 放进最⼩堆 min.offer(num); // 把最⼩的放进最⼤堆 max.offer(min.poll()); } } public Double GetMedian() { if (count % 2 == 0) { return (min.peek() + max.peek()) / 2.0; } else { return (double) min.peek(); } } }
  • 插入操作:堆的插入操作O(log n),平衡操作O(log n),总体O(log n)
  • 获取中位数:直接访问堆顶元素,O(1)时间复杂度
http://www.jsqmd.com/news/1100840/

相关文章:

  • 用VirtualLab Fusion搞定光栅建模:从单光栅分析到复杂系统集成的保姆级教程
  • VisualCppRedist AIO:Windows运行库终极解决方案完整指南
  • Hi7003替代H5118:60V输入与模拟/PWM双模调光的国产升级方案
  • DC-DC电源中,什么是功率地?
  • Pandas 数据分析库常用操作大全
  • 别再手动画图了!用SuperMap iDesktop的‘获取投影面’功能,5分钟搞定三维模型二维化
  • VisualCppRedist AIO:告别DLL缺失烦恼的终极解决方案
  • 从YOLO到3D点云目标检测:原理、环境搭建与实战复现
  • 众包平台任务分发与防骗机制设计——以帮帮星球为例
  • 计算机毕业设计之基于教育数字化的可视化系统的设计与实现
  • 别再手动写XML了!用Flowable UI拖拽式设计请假审批流程(附BPMN文件)
  • ANSYS APDL命令流实战:从截面特性到节点耦合,我的工程笔记大公开
  • 【Sora vs 可灵AI决策指南】:企业级视频生产选型必查的6个隐藏参数(含API吞吐量、长时序一致性、中文语义理解得分)
  • GPT Image 2 提示词教程:解决图片脏、模糊、有噪点的终极方法
  • 2026年6月国内外商城小程序开发公司测评:按价格区间、开发方式和交付能力选择,含零代码SAAS、AI编程、源码定制
  • 告别字符串处理噩梦:用MySQL的regexp_replace、regexp_substr、regexp_instr函数搞定数据清洗
  • 从‘123456’到‘字节密码密码蕴含’:用Python secrets打造你的专属XKCD风格密码生成器
  • 世界模型岗年薪250万仍缺人,可你的AI连旋转都算不准——2026下半年最该补的不是框架是这条公理
  • Cadence Allegro 17.4保姆级教程:从DRC检查到Gerber文件压缩,一次搞定PCB打样
  • Vue3 + Cesium 实战:5分钟搞定飞机GLB模型加载与视角追踪
  • 穿戴式脑电仪采集技术对比:湿电极vs干电极vs水电极
  • 3个简单步骤:让Switch手柄在Windows电脑上完美运行游戏
  • 宇视天目系列卡口电警工勘避坑指南:手把手教你用《智能交通工勘计算表》搞定现场参数
  • SQL注入攻防:从回显注入到盲注的实战技巧与防御策略
  • 选Wi-Fi模组别只盯着双核,这颗单核型号才是纯联网场景的务实之选
  • ArcMap制图进阶:手把手教你搞定‘一幅多图’布局与经纬网美化(ArcGIS 10.4.1)
  • 别再手动点来点去了!用Python脚本玩转dSPACE ModelDesk与ControlDesk自动化
  • OpenCV+YOLO:快速搭建机器人视觉感知系统,实现实时目标检测
  • 京东商品评论API接口讲解
  • 别再手动切视频了!用Python的pyscenedetect库,5分钟搞定视频自动场景分割