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

海量数据中找出最大的前100个(find_topk)最小堆算法

我来帮你实现这个寻找前100个最大数据的算法。这个算法的时间复杂度是O(n log 100),空间复杂度是O(100)。

C++实现

#include<iostream>#include<vector>#include<queue>#include<functional>#include<random>usingnamespacestd;// 寻找前k个最大元素的算法vector<int>findTopK(constvector<int>&nums,intk){if(nums.size()<=k){vector<int>result(nums.begin(),nums.end());returnresult;}// 创建最小堆priority_queue<int,vector<int>,greater<int>>minHeap;// 步骤1: 插入前k个元素for(inti=0;i<k;i++){minHeap.push(nums[i]);}// 步骤2-3: 遍历剩余元素,维护堆for(size_t i=k;i<nums.size();i++){if(nums[i]>minHeap.top()){minHeap.pop();// 弹出堆顶minHeap.push(nums[i]);// 插入当前元素}}// 步骤4: 堆中元素即为前k个最大数据vector<int>result;while(!minHeap.empty()){result.push_back(minHeap.top());minHeap.pop();}returnresult;}intmain(){// 生成测试数据vector<int>data(1000);random_device rd;mt19937gen(rd());uniform_int_distribution<>dis(1,10000);for(inti=0;i<1000;i++){data[i]=dis(gen);}intk=100;vector<int>topK=findTopK(data,k);cout<<"前"<<k<<"个最大元素:"<<endl;for(size_t i=0;i<topK.size();i++){cout<<topK[i]<<" ";if((i+1)%10==0)cout<<endl;}cout<<endl;return0;}

Python实现

importheapqimportrandomfromtypingimportListdeffind_top_k(nums:List[int],k:int)->List[int]:""" 寻找前k个最大元素的算法 实现步骤: 1. 创建一个最小堆并将前k个数据插入堆中 2. 遍历剩余的数据,如果当前数据比堆顶大,就替换堆顶元素 3. 继续遍历所有数据,确保堆中保留的是最大的k个数据 4. 遍历完成后,堆中的元素就是前k个最大的数据 """iflen(nums)<=k:returnsorted(nums,reverse=True)# 步骤1: 创建最小堆并插入前k个元素min_heap=nums[:k]heapq.heapify(min_heap)# 建立最小堆# 步骤2-3: 遍历剩余元素,维护堆fornuminnums[k:]:ifnum>min_heap[0]:# 如果当前元素比堆顶大# 弹出堆顶,插入当前元素heapq.heapreplace(min_heap,num)# 步骤4: 堆中元素即为前k个最大数据# 堆是最小堆,需要排序后返回result=sorted(min_heap,reverse=True)returnresultdeffind_top_k_alternative(nums:List[int],k:int)->List[int]:"""另一种实现方式,更清晰地体现算法步骤"""iflen(nums)<=k:returnsorted(nums,reverse=True)# 步骤1: 创建最小堆并插入前k个元素min_heap=[]foriinrange(k):heapq.heappush(min_heap,nums[i])# 步骤2-3: 遍历剩余数据foriinrange(k,len(nums)):ifnums[i]>min_heap[0]:# 比堆顶大# 我就往堆里面插heapq.heappop(min_heap)# 弹出堆顶heapq.heappush(min_heap,nums[i])# 插入当前数据# 步骤4: 返回结果returnsorted(min_heap,reverse=True)defmain():# 生成测试数据random.seed(42)data=[random.randint(1,10000)for_inrange(1000)]k=100# 使用方法1top_k=find_top_k(data,k)print(f"前{k}个最大元素:")fori,numinenumerate(top_k,1):print(f"{num:6d}",end=" ")ifi%10==0:print()print()# 验证结果正确性sorted_data=sorted(data,reverse=True)[:k]print(f"算法结果是否正确:{top_k==sorted_data}")# 使用方法2top_k2=find_top_k_alternative(data,k)print(f"方法2结果是否正确:{sorted(top_k2)==sorted(top_k)}")if__name__=="__main__":main()

算法复杂度分析

  • 时间复杂度: O(n log k),其中n是总数据量,k=100
  • 空间复杂度: O(k),只需要维护大小为100的堆

关键点说明

  1. 使用最小堆的原因:我们想要最大的k个元素,使用最小堆可以让我们在O(1)时间内知道当前堆中最小的元素
  2. 堆顶的作用:堆顶始终是当前堆中最小的元素,也就是第k大的候选者
  3. 替换条件:只有当新元素大于堆顶时,才进行替换,确保堆中始终是见过的最大的k个元素
  4. “我就往堆里面插”:这个操作在代码中体现为
    "heapq.heapreplace()"或先pop再push的操作

两种实现方式都可以,Python版本提供了两种写法:

    “find_top_k”:使用
    “heapq.heapreplace()”,更简洁

    “find_top_k_alternative”:分步操作,更清晰地体现算法步骤

    http://www.cnnetsun.cn/news/24763.html

    相关文章:

  • Claude Code Router多模型集成实战:打造智能开发工作流
  • 水稻病害检测(YOLO数据集,多分类,稻瘟病、纹枯病、褐斑病、枯心病、霜霉病、水稻细菌性条纹斑病、稻苞虫)
  • ABB机器人省气装置在薄板焊接中的实际效果
  • 京东Java面试被问:ZGC的染色指针如何实现?内存屏障如何处理?
  • 硬件 - 高速协议设计整合
  • Vue3如何设计百万文件上传的进度监控界面?
  • 黑芝麻智能与元戎启行达成深度合作,共推高阶辅助驾驶技术量产落地
  • Steamless终极指南:深度解析DRM移除技术与多场景应用
  • 如何在消费级显卡上运行Llama-Factory进行模型微调?
  • Qwen-Edit多角度控制插件:零基础快速掌握12种镜头变换技巧
  • Layui表格终极指南:实现行拖拽排序功能的完整解决方案
  • 广州市中二文化传播公司的知识图谱
  • 毕业设计 人脸识别学生课堂考勤专注检测系统(项目+论文)
  • Trae Agent智能代码审查:提升开发质量的全流程指南
  • LEEAlert 终极指南:打造惊艳iOS弹窗的完整教程
  • Intel One Mono:专为开发者设计的开源等宽字体完整指南
  • PySceneDetect视频场景智能分割完整指南:告别手动剪辑的烦恼
  • FP8量化训练实战指南:让大模型训练速度翻倍的秘密武器
  • 穿越时空的智慧:天干地支如何重塑你的现代生活节奏
  • Rush Stack Lockfile Explorer:解决大型项目依赖冲突的终极指南
  • 2025-12-12 全国各地响应最快的 BT Tracker 服务器(电信版)
  • 突破传统字体限制:Mona Sans可变字体解决方案
  • PySceneDetect终极指南:智能视频场景检测与自动分割完整教程
  • Warp框架v0.4迁移实战:从破局到精通的完整攻略
  • 终极3D生成革命:腾讯Hunyuan3D-2mv让建模效率飙升40倍
  • H5可视化编辑器终极指南:无需编码快速制作专业H5页面
  • 终极便携:VLC播放器绿色免安装版完整使用指南
  • RabbitMQ 核心概念与工作模式全解析
  • 10个颠覆传统编程思维的Go开源项目精选
  • 3分钟学会atm-cli:让MIDI文件生成变得如此简单