news 2026/3/11 13:33:51

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
海量数据中找出最大的前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”:分步操作,更清晰地体现算法步骤

    版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
    网站建设 2026/3/10 10:12:48

    因子归因:量化策略的风险诊断与收益解码

    因子归因&#xff1a;量化策略的风险诊断与收益解码 【免费下载链接】gs-quant 用于量化金融的Python工具包。 项目地址: https://gitcode.com/GitHub_Trending/gs/gs-quant 你的量化策略是否隐藏着未知的风险敞口&#xff1f;那些看似优秀的超额收益背后&#xff0c;究…

    作者头像 李华
    网站建设 2026/3/9 10:55:44

    面向动态Shape的通用融合算子设计-从理论到昇腾CANN工程实践

    目录 &#x1f50d; 摘要 1 &#x1f3af; 动态Shape处理的挑战与价值 1.1 从静态到动态的范式转变必要性 1.2 动态Shape的技术挑战深度分析 2 &#x1f3d7;️ CANN动态Shape支持架构解析 2.1 多层次动态Tiling机制 2.2 动态Shape的Workspace管理机制 3 ⚙️ 动态Tili…

    作者头像 李华
    网站建设 2026/3/11 12:31:45

    计算机组成原理

    &#x1f4c5; 模块一&#xff1a;数据的表示与运算 (选择题高发区) 复习目标&#xff1a; 拿满选择题分数&#xff0c;搞定大题中的某些小问&#xff08;如溢出判断&#xff09;。状态题目类型必刷题目 (年份-题号)核心考点 (必须能口述原理)[ ]必刷大题2025-44 (必做预测)201…

    作者头像 李华
    网站建设 2026/3/8 10:36:30

    Flash线性注意力终极指南:从核心原理到实践应用

    Flash线性注意力终极指南&#xff1a;从核心原理到实践应用 【免费下载链接】flash-linear-attention Efficient implementations of state-of-the-art linear attention models in Pytorch and Triton 项目地址: https://gitcode.com/GitHub_Trending/fl/flash-linear-atten…

    作者头像 李华
    网站建设 2026/3/11 9:57:46

    NavVis三维扫描助力ETM体育场翻降本增效【上海巷尚】

    项目难点&#xff1a;ETM正在为佛罗里达州杰克逊维尔市大型体育场翻新工程提供支持。该工程以体育设施升级为核心&#xff0c;其数字孪生构建工作的核心难点在于“大”与“精”之间的矛盾。1.作业时间繁长采用传统静态方法拍摄体育场内部范围&#xff0c;约需60个工作日。2.几何…

    作者头像 李华
    网站建设 2026/3/11 12:59:35

    递归:不止是 “自己调用自己”,看完这篇秒懂

    递归&#xff1a;不止是 “自己调用自己”&#xff0c;看完这篇秒懂你有没有玩过俄罗斯套娃&#xff1f;打开一个&#xff0c;里面还有一个&#xff0c;再打开&#xff0c;还有一个…… 直到最后一个最小的娃娃出现&#xff0c;游戏才结束。其实在编程世界里&#xff0c;也有这…

    作者头像 李华