topK问题解法
topK问题的最佳解法是堆排,下面介绍用堆排来解决该问题。
堆排解决topK问题的思路,取出前K个数,最重要的就是要减少比较的次数,用堆排维护一个K大小的堆,比如一个小顶堆,则堆顶为堆中最小的值,将堆外的元素依次与堆顶比较,若大于堆顶,则与堆顶交换,并将堆重新调整为小顶堆,依次比较完所有元素。则堆顶为堆中的最小元素,且为所有元素中的第K大的元素,则整个堆则为前K大的K个元素。若要取前K个小的数,则要使用大顶堆。
测试代码如下:
var array = [10,7,8,6,3,1,5,2,4,9]; var k =6; var len = array.length; fHeapSortK(array,len,k); console.log('topK result: ' + array); //堆排取出top K数据,小顶堆取最大的前K个数据,大顶堆取最小的前K个数据 function fHeapSortK(data,length,k){ fBuildSmallHeap(data,k); //将前k个后面的数字,依次与堆顶比较,大于堆顶,就与堆顶交换 for(var i=k;i<length;i++){ if(data[i] > data[0]){ //交换堆顶与较大值 swap(data,0,i); //0至k-1,前面K个数字调整为小顶堆 fAdjustSmallHeap(data,0,k-1); } } } //构造小顶堆 function fBuildSmallHeap(data,length){ //length是堆的大小,前K个数字,则是需要一个K长度的堆 //将数组中的前 m = Math.floor(length/2) 作为父节点,后面 length - m 个节点,都是父节点的孩子节点 //依次将所有父节点为三角形的堆,都调整为小顶堆,这样整个length长度的堆,就调整为一个小顶堆 //调整过程是递归的过程,实际发生的调整次数,不只 m 次 for(var i = Math.floor(length/2);i--;){ fAdjustSmallHeap(data,i,length); } console.log('small heap ' + data) } //调整堆为小顶堆 function fAdjustSmallHeap(data,loc,length){ var lChild = 2 * loc + 1, rChild = 2 * loc + 2, smallest = loc; //判断左孩子,是否小于,小于就交换 if(lChild <= length && data[lChild] < data[smallest]){ smallest = lChild; } //判断有孩子,是否小于,小于就交换 if(rChild <= length && data[rChild] < data[smallest]){ smallest = rChild; } //最小索引不是原父节点的索引,则需要交换父节点和孩子 if(smallest != loc){ //交换父节点与左右孩子中最小的节点 swap(data,loc,smallest); //交换后,父节点为孩子的三角形,要继续调整为小顶堆,爷爷节点为孩子的也要调整,递归进行 fAdjustSmallHeap(data,smallest,length); } } //交换数据 function swap(data,a,b){ var temp = data[a]; data[a] = data[b]; data[b] = temp; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具