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;
}

topK问题解法的更多相关文章

  1. topk两种解法

    1.这个通过partition实现topk,时间复杂度是o(logn*logn),也就是0(n),但需要修改原数组的顺序 下面这个代码本身有一些错误,并且throw excption会在牛客上报错 c ...

  2. PHP 十万数字不同数组取最大的5个 (经典面试题topK) (原)

    $arr = array(3,5,7,8,1,2,456,78,...101,2345,456); 类似上述数组,共有十万个元素,让我们取出TOP5,下面是我的解法,先上代码再讲解思路 functio ...

  3. 海量数据中的TOPK问题小结

    1.利用堆找出最大的K个数 首先,先理解下用堆找出最大的K个数的常用解法,例如问题是“从M(M <= 10000)个数中找出最大的K个数” (1)利用最大堆 建立一个N=M大小的大顶堆,然后输出 ...

  4. 【Leetcode 堆、快速选择、Top-K问题 BFPRT】数组中的第K个最大元素(215)

    这道题很强大,引出了很多知识点 题目 在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: 输入: [3,2,1,5 ...

  5. 215. 数组中的第K个最大元素(TOP-K问题)

    问题: 在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: 输入: [3,2,1,5,6,4] 和 k = 2输出 ...

  6. 如何解决TOP-K问题

    前言:最近在开发一个功能:动态展示的订单数量排名前10的城市,这是一个典型的Top-k问题,其中k=10,也就是说找到一个集合中的前10名.实际生活中Top-K的问题非常广泛,比如:微博热搜的前100 ...

  7. 一文详解面试常考的TopK问题

    首发公众号:bigsai ,转载请附上本文链接 前言 hello,大家好,我是bigsai哥哥,好久不见,甚是想念哇! 今天给大家分享一个TOPK问题,不过我这里不考虑特别大分布式的解决方案,普通的一 ...

  8. alias导致virtualenv异常的分析和解法

    title: alias导致virtualenv异常的分析和解法 toc: true comments: true date: 2016-06-27 23:40:56 tags: [OS X, ZSH ...

  9. Matlab数值计算示例: 牛顿插值法、LU分解法、拉格朗日插值法、牛顿插值法

    本文源于一次课题作业,部分自己写的,部分借用了网上的demo 牛顿迭代法(1) x=1:0.01:2; y=x.^3-x.^2+sin(x)-1; plot(x,y,'linewidth',2);gr ...

随机推荐

  1. OO第四单元总结

    单元架构设计 本单元OO作业主要涉及两个过程,即先根据输入的elements数组建立UML存储模型,而后基于这个模型实现一系列查询判断功能.汲取上单元的经验,建模过程中模型数据容器的选择依据要求实现的 ...

  2. MySQL的入门与使用,sqlyog对数据库,表和数据的管理

    MySQL的入门 1.到mysql官网下载. 2.安装mysql软件(一定要放到英文路径下) 3.使用 验证是否成功 将mySQL的bin路径添加到系统环境变量Path中 打开dos命令窗口 Wind ...

  3. React后台管理系统-ajax请求封装

    1.新建文件夹 util , 在util里边新建 mm.jsx文件 2.使用jquery里边的ajax发送请求,回调用promise,返回一个promise对象 request(param){     ...

  4. 第22题:链表中倒数第k个结点

    题目描述 题目:输入一个链表,输出该链表中倒数第k个结点.为了符合大多数人的习惯,本题从1开始计数,即链表的尾结点是倒数第1个结点.例如一个链表有6个结点,从头结点开始它们的值依次是1.2.3.4.5 ...

  5. 算法竞赛入门经典5.1 从c到c++

    这个章节主要是讲述了一些c++的特性,在这里面,对我用处最大的应该就是字符串吧.首先是getline,getchar,stringstream的使用了吧. 首先介绍这三个函数. 1. getline函 ...

  6. 深入理解java虚拟机读书笔记1--java内存区域

    Java在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途.创建和销毁的时间,有一些是随虚拟机的启动而创建,随虚拟机的退出而销毁,有些则是与线程一一对应,随 ...

  7. 通过rsync+inotify实现数据实时备份

    rsync的优点与不足 与传统的cp,scp,tar,备份方式相比,rsync具有安全性高备份迅速支持增量备份的优点,可以满足对实时性要求不高的需求,例如定期备份文件服务器数据到远端服务器,但是,当数 ...

  8. python之2.x与3.x区别(仅限于基础)

    因为看的是python2.x的书籍.用的是python 3.7.所以先把两者的区别记录一下,仅限于基础. 1.input python3.0之后,不区分input()和raw_input(),统一为i ...

  9. Python_深浅拷贝

    深浅拷贝 ‘copy’和'='的区别:copy会开辟一个新的空间,而‘=’不会. 浅copy只会copy第一层,再里边的就进行共享了. 需要记住的是copy之后记住的是内存寻址地址,而浅copy时如果 ...

  10. js字符串去掉所有空格

    字符串去掉所有空格 "abc 123 def".replace(/\s/g, "") 字符串去掉左右两端空格 " abc 123 def " ...