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

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:

在这里插入图片描述

相关文章:

  • Wan2.1 图生视频 多卡推理批量生成视频
  • 视频问答功能播放器(视频问答)视频弹题功能实例
  • ffmpeg转换竖屏(画面是横屏旋转90度的竖屏文件格式)视频到横屏
  • 网易互娱游戏研发实习一面
  • 在 ElementUI 中实现 Table 单元格合并
  • 萤石云实际视频实时接入(生产环境)
  • Node.js全局对象详解:console、process与核心功能
  • [ARM][架构] 01.ARMv7 特权等级与核心寄存器
  • 代码随想录算法训练营第60期第四十八天打卡
  • 开源 FcDesigner 表单设计器组件事件详解
  • 算法打卡第七天
  • 【ARTS】【LeetCode-59】螺旋矩阵
  • Debian系统安装Python详细教程及常见问题解答
  • Leetcode 3563. Lexicographically Smallest String After Adjacent Removals
  • Steam发布游戏过程的若干问题
  • 【计算机网络】IP 协议深度解析:从基础到实战
  • 晚期NSCLC临床试验终点与分析策略
  • 重学计算机网络之命令整理
  • 【Bug】--node命令加载失败
  • 重磅升级!Docusign IAM 2025 V1 版本上线,重塑智能协议新体验
  • 做企业网站设计/一个完整的策划案范文
  • 手机网站 ui/珠海网站建设制作
  • 常熟网站建设/最新百度快速排名技术
  • 工控人如何做自己的网站/搜索引擎营销题库和答案
  • 自建网站与平台建站/产品推广ppt范例
  • 酒店专业培训网站建设/网络营销中心