海量数据处理之top K问题
Top k问题的讨论(三种方法的java实现及适用范围)
在很多的笔试和面试中,喜欢考察Top K.下面从自身的经验给出三种实现方式及实用范围。
- 合并法
这种方法适用于几个数组有序的情况,来求Top k。时间复杂度为O(k*m)。(m:为数组的个数).具体实现如下:

/**
* 已知几个递减有序的m个数组,求这几个数据前k大的数
*适合采用Merge的方法,时间复杂度(O(k*m);
*/
import java.util.List;
import java.util.Arrays;
import java.util.ArrayList;
public class TopKByMerge{
public int[] getTopK(List<List<Integer>>input,int k){
int index[]=new int[input.size()];//保存每个数组下标扫描的位置;
int result[]=new int[k];
for(int i=0;i<k;i++){
int max=Integer.MIN_VALUE;
int maxIndex=0;
for(int j=0;j<input.size();j++){
if(index[j]<input.get(j).size()){
if(max<input.get(j).get(index[j])){
max=input.get(j).get(index[j]);
maxIndex=j;
}
}
}
if(max==Integer.MIN_VALUE){
return result;
}
result[i]=max;
index[maxIndex]+=1; }
return result;
}

- 快排过程法
快排过程法利用快速排序的过程来求Top k.平均时间复杂度为(O(n)).适用于无序单个数组。具体java实现如下:
Quick Select的目标是找出第k大元素,所以
选取一个基准元素pivot,将数组切分(partition)为两个子数组,
- 若切分后的左子数组的长度 > k,则第k大元素必出现在左子数组中;
- 若切分后的左子数组的长度 = k-1,则第k大元素为pivot;
- 若上述两个条件均不满足,则第k大元素必出现在右子数组中。

/*
*利用快速排序的过程来求最小的k个数
*
*/
public class TopK{
int partion(int a[],int first,int end){
int i=first;
int main=a[end];
for(int j=first;j<end;j++){
if(a[j]<main){
int temp=a[j];
a[j]=a[i];
a[i]=temp;
i++;
}
}
a[end]=a[i];
a[i]=main;
return i;
}
void getTopKMinBySort(int a[],int first,int end,int k){
if(first<end){
int partionIndex=partion(a,first,end);
if(partionIndex==k-1)return;
else if(partionIndex>k-1)getTopKMinBySort(a,first,partionIndex-1,k);
else getTopKMinBySort(a,partionIndex+1,end,k);
}
}
public static void main(String []args){
int a[]={2,20,3,7,9,1,17,18,0,4};
int k=6;
new TopK().getTopKMinBySort(a,0,a.length-1,k);
for(int i=0;i<k;i++){
System.out.print(a[i]+" ");
}
}
}

- 采用小根堆或者大根堆
求最大K个采用小根堆,而求最小K个采用大根堆。
求最大K个的步奏:
- 根据数据前K个建立K个节点的小根堆。
- 在后面的N-K的数据的扫描中,
- 如果数据大于小根堆的根节点,则根节点的值覆为该数据,并调节节点至小根堆。
- 如果数据小于或等于小根堆的根节点,小根堆无变化。
求最小K个跟这求最大K个类似。时间复杂度O(nlogK)(n:数据的长度),特别适用于大数据的求Top K。

/**
* 求前面的最大K个 解决方案:小根堆 (数据量比较大(特别是大到内存不可以容纳)时,偏向于采用堆)
*
*
*/
public class TopK {
/**
* 创建k个节点的小根堆
*
* @param a
* @param k
* @return
*/
int[] createHeap(int a[], int k) {
int[] result = new int[k];
for (int i = 0; i < k; i++) {
result[i] = a[i];
}
for (int i = 1; i < k; i++) {
int child = i;
int parent = (i - 1) / 2;
int temp = a[i];
while (parent >= 0 &&child!=0&& result[parent] >temp) {
result[child] = result[parent];
child = parent;
parent = (parent - 1) / 2;
}
result[child] = temp;
}
return result; } void insert(int a[], int value) {
a[0]=value;
int parent=0; while(parent<a.length){
int lchild=2*parent+1;
int rchild=2*parent+2;
int minIndex=parent;
if(lchild<a.length&&a[parent]>a[lchild]){
minIndex=lchild;
}
if(rchild<a.length&&a[minIndex]>a[rchild]){
minIndex=rchild;
}
if(minIndex==parent){
break;
}else{
int temp=a[parent];
a[parent]=a[minIndex];
a[minIndex]=temp;
parent=minIndex;
}
} } int[] getTopKByHeap(int input[], int k) {
int heap[] = this.createHeap(input, k);
for(int i=k;i<input.length;i++){
if(input[i]>heap[0]){
this.insert(heap, input[i]);
} }
return heap; } public static void main(String[] args) {
int a[] = { 4, 3, 5, 1, 2,8,9,10};
int result[] = new TopK().getTopKByHeap(a, 3);
for (int temp : result) {
System.out.println(temp);
}
}
}

海量数据处理之top K问题的更多相关文章
- 海量数据处理的 Top K 相关问题
Top-k的最小堆解决方法 问题描述:有N(N>>10000)个整数,求出其中的前K个最大的数.(称作Top k或者Top 10) 问题分析:由于(1)输入的大量数据:(2)只要前K个,对 ...
- 海量数据处理 - 10亿个数中找出最大的10000个数(top K问题)
前两天面试3面学长问我的这个问题(想说TEG的3个面试学长都是好和蔼,希望能完成最后一面,各方面原因造成我无比想去鹅场的心已经按捺不住了),这个问题还是建立最小堆比较好一些. 先拿10000个数建堆, ...
- july教你如何迅速秒杀掉:99%的海量数据处理面试题
作者:July出处:结构之法算法之道blog 以下是原博客链接网址 http://blog.csdn.net/v_july_v/article/details/7382693 微软面试100题系列 h ...
- 程序员编程艺术:第三章续、Top K算法问题的实现
程序员编程艺术:第三章续.Top K算法问题的实现 作者:July,zhouzhenren,yansha. 致谢:微软100题实现组,狂想曲创作组. 时间:2011年05月08日 ...
- 如何解决海量数据的Top K问题
1. 问题描述 在大规模数据处理中,常遇到的一类问题是,在海量数据中找出出现频率最高的前K个数,或者从海量数据中找出最大的前K个数,这类问题通常称为“top K”问题,如:在搜索引擎中,统计搜索最热门 ...
- (面试)Hash表算法十道海量数据处理面试题
Hash表算法处理海量数据处理面试题 主要针对遇到的海量数据处理问题进行分析,参考互联网上的面试题及相关处理方法,归纳为三种问题 (1)数据量大,内存小情况处理方式(分而治之+Hash映射) (2)判 ...
- 海量数据处理面试题学习zz
来吧骚年,看看海量数据处理方面的面试题吧. 原文:(Link, 其实引自这里 Link, 而这个又是 Link 的总结) 另外还有一个系列,挺好的:http://blog.csdn.net/v_jul ...
- 海量数据处理算法—Bloom Filter
海量数据处理算法—Bloom Filter 1. Bloom-Filter算法简介 Bloom-Filter,即布隆过滤器,1970年由Bloom中提出.它可以用于检索一个元素是否在一个集合中. Bl ...
- 经典面试问题: Top K 之 ---- 海量数据找出现次数最多或,不重复的。
作者:林冠宏 / 指尖下的幽灵 掘金:https://juejin.im/user/587f0dfe128fe100570ce2d8 博客:http://www.cnblogs.com/linguan ...
随机推荐
- 虚拟机与Docker有何不同
http://www.techug.com/post/comparing-virtual-machines-vs-docker-containers.html 译者按: 各种虚拟机技术开启了云计算时代 ...
- ASP.net MVC5 Code First填充测试数据到数据库
问题的产生 最近在看Adam Freeman的“Pro ASP.NET MVC5”,于是在工作机上面搭建了相应的运行环境,但是在自己的机器上面只有代码,没有数据库.记得在code first中可以新 ...
- Python基础(三)文件操作
[对文件进行循环操作] fw = open('nhy','w') for line in fw: print('line:',line) #直接循环文件对象,每次循环的时候就是取每一行的数据 fw ...
- jvm 线上命令
jstat -gc 40015 查看jvm用的是什么gc算法 java -XX:+PrintCommandLineFlags -version
- java String 类型总结
java中String是个对象,是引用类型?,基础类型与引用类型的区别是,基础类型只表示简单的字符或数字,引用类型可以是任何复杂的数据结构,基本类型仅表示简单的数据类型,引用类型可以表示复杂的数据类型 ...
- easyUI 创建详情页dialog
使用easyui dialog先下载jQuery easyui 的压缩包 下载地址http://www.jeasyui.com/download/v155.php 解压后放在项目WebContent ...
- lvs 进阶 第二章
linux virtual server 一 . lvs lvs 对数据进行四层转发,根据目标地址和目标端口对请求数据进行转发. lvs 包含ipvsadm 和ipvs: ipvsadm :用户空间的 ...
- Html br 标签
Html br 标签 <html> <body> <!-- br标签:跳到下一行--> <p>内<br />容</p> 注:br ...
- 剑指offer(64)滑动窗口中的最大值
题目描述 给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值.例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6 ...
- 手游折扣app排行榜前10名_2018哪个折扣app最低最好
2018游戏圈白皮书发布,PC端游的份额继续下降,页游的比例也在下降,但手游的比例持续3年上升.以渠道为阵营,逐渐小的平台和公会被逐渐淘汰.流量集中在少数几个大的平台.但是这样带来的问题是,平台越来越 ...