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. form 表单 和 jQuery HTML / CSS 方法($().html 类似的样式)

    1 有关链接 :http://www.runoob.com/tags/tag-form.html https://www.cnblogs.com/Jxwz/p/4509618.html https:/ ...

  2. common-fileupload组件实现java文件上传和下载

    简介:文件上传和下载是java web中常见的操作,文件上传主要是将文件通过IO流传放到服务器的某一个特定的文件夹下,而文件下载则是与文件上传相反,将文件从服务器的特定的文件夹下的文件通过IO流下载到 ...

  3. 【函数应用】PHP中关于URL的函数处理

    一,函数介绍 1.解析HTTP头信息:get_header() array get_headers ( string 目标URL [, int $format = 0 [如果将可选的 format 参 ...

  4. 微信在浏览器打开前的提示页面Android与IOS判断

    直接在网上扒一个页面,分分钟搞定!  先看一下效果 这是用微信开发工具打开的样式,直接上完整代码 <!DOCTYPE html> <html lang="en"& ...

  5. Swiper.js手动滑动之后,不再自动滑动问题

    var swiper = new Swiper('.swiper-container', {        pagination: '.swiper-pagination',        autop ...

  6. DeepFaceLab报错, Could not create cudnn handle 解决方法!

    DeepFaceLab 虽然没有可视化界面,但是在众多换脸软件中,是安装最方便,更新最快,整体性能最佳的一个.这个软件对于系统依赖很低,也就是不需要装各种各样的“插件”. 但是即便如此,由于版本的不断 ...

  7. 动态拼接SQL语句

    1.参考官方文档 ? if:字符判断 ? choose (when, otherwise):分支选择 ? trim (where, set):字符串截取:其中where标签封装查询条件,set标签封装 ...

  8. Leetcode 106. 从中序与后序遍历序列构造二叉树

    题目链接 https://leetcode.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/descri ...

  9. UVALive 4685 Succession 树DP+背包

    一.前言 这道题同样来自于红书P142,作为树DP专题中的一道比较难的题目,A了一天左右的时间,看上去事实证明,这题的难度理我本身的实力还是有些太远了,于是正确的做法应该是分析一下题目之后进行解析什么 ...

  10. 多进程的基本使用--multiprocessing 【转】

    multiprocessing 如果你打算编写多进程的服务程序,Unix/Linux无疑是正确的选择.由于Windows没有fork调用,难道在Windows上无法用Python编写多进程的程序? 由 ...