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

leetcode-295 Find Median from Data Stream

class MaxHeap {private heap: number[];constructor() {this.heap = [];}// 插入元素并上浮调整push(num: number): void {this.heap.push(num);this.siftUp(this.heap.length - 1);}// 弹出堆顶元素并下沉调整pop(): number {const top = this.heap[0];const last = this.heap.pop()!;if (this.heap.length > 0) {this.heap[0] = last;this.siftDown(0);}return top;}// 堆顶元素peek(): number {return this.heap[0];}size(): number {return this.heap.length;}// 上浮操作private siftUp(index: number): void {while (index > 0) {const parent = Math.floor((index - 1) / 2);if (this.heap[parent] >= this.heap[index]) break;[this.heap[parent], this.heap[index]] = [this.heap[index],this.heap[parent],];index = parent;}}// 下沉操作private siftDown(index: number): void {const size = this.size();while (index < size) {let left = 2 * index + 1;let right = 2 * index + 2;let largest = index;if (left < size && this.heap[left] > this.heap[largest]) largest = left;if (right < size && this.heap[right] > this.heap[largest])largest = right;if (largest === index) break;[this.heap[index], this.heap[largest]] = [this.heap[largest],this.heap[index],];index = largest;}}
}class MinHeap {private heap: number[];constructor() {this.heap = [];}push(num: number): void {this.heap.push(num);this.siftUp(this.heap.length - 1);}pop(): number {const top = this.heap[0];const last = this.heap.pop()!;if (this.heap.length > 0) {this.heap[0] = last;this.siftDown(0);}return top;}peek(): number {return this.heap[0];}size(): number {return this.heap.length;}private siftUp(index: number): void {while (index > 0) {const parent = Math.floor((index - 1) / 2);if (this.heap[parent] <= this.heap[index]) break;[this.heap[parent], this.heap[index]] = [this.heap[index],this.heap[parent],];index = parent;}}private siftDown(index: number): void {const size = this.size();while (index < size) {let left = 2 * index + 1;let right = 2 * index + 2;let smallest = index;if (left < size && this.heap[left] < this.heap[smallest]) smallest = left;if (right < size && this.heap[right] < this.heap[smallest])smallest = right;if (smallest === index) break;[this.heap[index], this.heap[smallest]] = [this.heap[smallest],this.heap[index],];index = smallest;}}
}
class MedianFinder {private maxHeap: MaxHeap; // 较小的一半(最大堆)private minHeap: MinHeap; // 较大的一半(最小堆)constructor() {this.maxHeap = new MaxHeap();this.minHeap = new MinHeap();}addNum(num: number): void {// 优先插入最大堆this.maxHeap.push(num);// 将最大堆的堆顶移动到最小堆(确保最大堆堆顶 ≤ 最小堆堆顶)this.minHeap.push(this.maxHeap.pop());// 平衡堆大小,确保最大堆大小 >= 最小堆if (this.maxHeap.size() < this.minHeap.size()) {this.maxHeap.push(this.minHeap.pop());}}findMedian(): number {if (this.maxHeap.size() === this.minHeap.size()) {return (this.maxHeap.peek() + this.minHeap.peek()) / 2;} else {return this.maxHeap.peek();}}
}//分块加载
function calculateExactMedian(data: number[], chunkSize: number) {const chunks = [];// 分块加载数据for (let i = 0; i < data.length; i += chunkSize) {const chunk = data.slice(i, i + chunkSize);chunks.push(chunk);}// 对每个小块进行排序const sortedChunks = chunks.map((chunk) => chunk.sort((a, b) => a - b));// 合并所有排序后的块const mergedArray = [];sortedChunks.forEach((chunk) => {mergedArray.push(...chunk);});// 对合并后的数组进行排序mergedArray.sort((a, b) => a - b);// 计算中位数const length = mergedArray.length;if (length % 2 === 0) {return (mergedArray[length / 2 - 1] + mergedArray[length / 2]) / 2;} else {return mergedArray[Math.floor(length / 2)];}
}//测试中位数计算效率
const nums: number[] = [];
const len = 10 ** 7;
for (let i = 0; i < len; i++) {nums.push(Math.floor(Math.random() * 100));
}const $s = performance.now();
const medianFinder = new MedianFinder();
for (let i = 0; i < nums.length; i++) {medianFinder.addNum(nums[i]);
}
console.log(medianFinder.findMedian()); // 输出中位数
const $e = performance.now();
console.log($e - $s, '@heap_sort');//使用普通数组的方式
const $s1 = performance.now();
nums.sort((a, b) => a - b); // 排序
const n = nums.length;
if (n % 2 === 0) {console.log((nums[n / 2 - 1] + nums[n / 2]) / 2); // 偶数个元素,取中间两个的平均值
} else {console.log(nums[Math.floor(n / 2)]); // 奇数个元素,取中间的元素}
}
const $e1 = performance.now();
console.log($e1 - $s1, '@arr_sort');// 设置块大小
const $s2 = performance.now();
const chunkSize = 10000;
console.log(calculateExactMedian(nums, chunkSize));
const $e2 = performance.now();
console.log($e2 - $s2, '@chunk_sort');

output:

在这里插入图片描述

http://www.lryc.cn/news/2386797.html

相关文章:

  • 【后端高阶面经:缓存篇】37、高并发系统缓存性能优化:从本地到分布式的全链路设计
  • 西门子 S1500 博途软件舞台威亚 3D 控制方案
  • 洛谷 P3374 【模板】树状数组 1(线段树解法)
  • 欣佰特科技| SIL2/PLd 认证 Inxpect毫米波安全雷达:3D 扫描 + 微小运动检测守护工业安全
  • 大模型量化原理
  • dify-api的.env配置文件
  • 【Linux】Linux 操作系统 - 18 , 重谈文件(二) ~ 文件描述符和重定向原理 , 手把手带你彻底理解 !!!
  • 第五十三节:综合项目实践-车牌识别系统
  • AI时代新词-AI伦理(AI Ethics)
  • 湖北理元理律师事务所债务优化服务中的“四维平衡“之道
  • Git Push 失败:HTTP 413 Request Entity Too Large
  • 第10章 网络与信息安全基础知识
  • GO语言学习(九)
  • go 访问 sftp 服务 github.com/pkg/sftp 的使用踩坑,连接未关闭(含 sftp 服务测试环境搭建)
  • Linux多线程(二)之进程vs线程
  • 【MogDB】测试 ubuntu server 22.04 LTS 安装mogdb 5.0.11
  • AI时代新词-数字孪生(Digital Twin)
  • 【HW系列】—web常规漏洞(文件上传漏洞)
  • 如何实现 C/C++ 与 Python 的通信
  • python炸鱼船
  • 使用AutoKeras2.0的AutoModel进行结构化数据回归预测
  • 好用但不常用的Git配置
  • ULVAC VWR-400M/ERH 真空蒸发器 Compact Vacuum Evaporator DEPOX (VWR-400M/ERH)
  • P1068 [NOIP 2009 普及组] 分数线划定
  • PPT连同备注页(演讲者模式)一块转为PDF
  • 第三十二天打卡
  • 项目三 - 任务8:实现词频统计功能
  • MongoDB 快速整合 SpringBoot 示例
  • 2025.05.22-得物春招机考真题解析-第二题
  • ollama list模型列表获取 接口代码