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

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.xdnf.cn/news/9036.html

相关文章:

  • 【科研绘图系列】R语言绘制柱状图(bar plot)
  • Vue中的 VueComponent
  • pytorch简单线性回归模型
  • 如何轻松地将文件从 iPhone 传输到 PC
  • Python基础教程:从零开始学习编程 - 第1-3天
  • 全光网络ICU床旁监护系统:重新定义重症监护的智慧中枢
  • python入门day01
  • UE5 Niagara Advance 学习笔记
  • git学习笔记
  • matlab实现激光腔长计算满足热透镜效应
  • JAVA 学习日志
  • 防火墙的SD-WAN功能
  • JAVA基础编程练习题--50道
  • 【Webtrees 用户手册】第 2 章 - 访客须知
  • 网易互娱游戏研发实习一面
  • ubuntu脚本常用命令
  • 海外呼叫中心优势与挑战分析
  • Bota Systems与Kinova合作:赋予AI机器人触觉能力
  • 如何给自研MCP加上安全验证
  • 类的设计模式——单例、工厂以及建造者模式
  • java-单列集合list与set。
  • 前端移动端上传图片pc端如何实时获取
  • 2 的 4 次方到 10 次方
  • android安卓模拟器中访问宿主机的开发接口服务
  • Axure元件动作七:移动、旋转、启用/禁用效果、置于顶层/底层详解
  • 芋道框架 - 接口设置匿名访问
  • 鸿蒙OSUniApp 实现的短信验证码登录功能#三方框架 #Uniapp
  • Numba模块的用法(高性能计算)
  • 类和对象(2)
  • LlamaFirewall:开源框架助力检测与缓解AI核心安全风险