问题:1亿数据中,找出最大的k个数,要求使用内存不超过1m

(延伸问题:1亿数据中,找出重复出现次数最多的k个,要求使用内存不超过1m 等)

分析:

1亿数字(int)占内存:100000000 * 4byte / 1024 / 1024 =381m

其中 int=4byte,1m=1024kb,1kb=1024b

实现:

维护一个k大小的数组有序数组。每次加进来新的,都要判断是不是 换掉 该数组中最小的元素,如果需要,则删除最小元素,放入新元素,并重新排序。

基于小顶堆的实现:

创建一个k大小的堆。TOP K堆只用维护固定数量的元素,每次加进来新的,都要判断是否替换掉堆顶元素,如果需要,则删除堆顶元素,放入新元素,并重新构造堆

时间复杂度O(nlnK)

public class TopK_ByHeapSort {

    //向小顶堆插入一个新的元素
public static void insertHeap(int[] heap, int value) {
heap[0] = value;
adjustHeap(heap, 0, heap.length);// 重新对堆进行调整
} //调整堆
public static void adjustHeap(int[] arr, int i, int length) {
int temp = arr[i];// 先取出当前元素i
for (int k = i * 2 + 1; k < length; k = k * 2 + 1) {// 从i结点的左子结点开始,也就是2i+1处开始
if (k + 1 < length && arr[k] > arr[k + 1]) {// 如果左子结点小于右子结点,k指向右子结点
k++;
}
if (arr[k] < temp) {// 如果子节点小于父节点,将子节点值赋给父节点(不用进行交换)
arr[i] = arr[k];
i = k;
} else {
break;
}
}
arr[i] = temp;// 将temp值放到最终的位置
} //构建小顶堆
public static void createMinHeap(int[] arr){
for (int i = arr.length / 2 - 1; i >= 0; i--) {
adjustHeap(arr, i, arr.length);
}
}
//交换元素
public static void swap(int[] arr, int a, int b) {
int temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
} //将小顶堆 转化为 有序数组
public static int[] minHeapToSortArr(int[] arr){
for (int j = arr.length - 1; j > 0; j--) {
swap(arr, 0, j);// 将堆顶元素与末尾元素进行交换
adjustHeap(arr, 0, j);// 重新对堆进行调整
}
return arr; } public static void print(int[] n) {
for (int i = 0; i < n.length; i++) {
System.out.print(" " + n[i]);
}
System.out.println();
}
//使用堆排序实现topk
public static int[] getTopKByHeap(int input[], int k) {
//构建k大小数组
int[] result = new int[k];
for (int i = 0; i < k; i++)
result[i] = input[i];
//构建小顶堆
createMinHeap(result); //将新元素插入小顶堆
for (int i = k; i < input.length; i++) {
if (input[i] > result[0])
insertHeap(result, input[i]); // 复杂度最坏是O(nlgK),而且内存消耗就K,不然海量数据排序,内存放不下,得用归并排序,最好最坏平均都是
}
//将小顶堆转化为有序数组
minHeapToSortArr(result);
return result;
} public static void main(String[] args) {
int input[] = { 37, 3, 5, 29, 2, 9, 10, 40, 99 };
int k=6;
print(getTopKByHeap(input, k));
}
}

延伸问题:1亿数据中,找出重复出现次数最多的k个,要求使用内存不超过1m

1亿数据占内存381m,可分成400批load到内存
1亿/400=25w
通过hash,大顶堆 分别计算每25w数据中重复次数最多的k个元素,然后合并这400个大顶堆

经典算法(一) top k的更多相关文章

  1. 经典面试问题: Top K 之 ---- 海量数据找出现次数最多或,不重复的。

    作者:林冠宏 / 指尖下的幽灵 掘金:https://juejin.im/user/587f0dfe128fe100570ce2d8 博客:http://www.cnblogs.com/linguan ...

  2. 必考算法之 Top K 问题

    大家好,这里是<齐姐聊算法>系列之 Top K 问题. Top K 问题是面试中非常常考的算法题. 8 Leetcode 上这两题大同小异,这里以第一题为例. 题意: 给一组词,统计出现频 ...

  3. 海量数据处理算法(top K问题)

    举例 有一个1G大小的一个文件,里面每一行是一个词,词的大小不超过16字节,内存限制大小是1M.返回频数最高的100个词. 思路 首先把文件分开 针对每个文件hash遍历,统计每个词语的频率 使用堆进 ...

  4. Top K问题-BFPRT算法、Parition算法

    BFPRT算法原理 在BFPTR算法中,仅仅是改变了快速排序Partion中的pivot值的选取,在快速排序中,我们始终选择第一个元素或者最后一个元素作为pivot,而在BFPTR算法中,每次选择五分 ...

  5. 优先队列实现 大小根堆 解决top k 问题

      摘于:http://my.oschina.net/leejun2005/blog/135085 目录:[ - ] 1.认识 PriorityQueue 2.应用:求 Top K 大/小 的元素 3 ...

  6. Top k问题(线性时间选择算法)

    问题描述:给定n个整数,求其中第k小的数. 分析:显然,对所有的数据进行排序,即很容易找到第k小的数.但是排序的时间复杂度较高,很难达到线性时间,哈希排序可以实现,但是需要另外的辅助空间. 这里我提供 ...

  7. 程序员编程艺术:第三章续、Top K算法问题的实现

    程序员编程艺术:第三章续.Top K算法问题的实现 作者:July,zhouzhenren,yansha.     致谢:微软100题实现组,狂想曲创作组.     时间:2011年05月08日    ...

  8. Top K算法

    应用场景: 搜索引擎会通过日志文件把用户每次检索使用的所有检索串都记录下来,每个查询串的长度为1-255字节.        假设目前有一千万个记录(这些查询串的重复度比较高,虽然总数是1千万,但如果 ...

  9. [经典算法题]寻找数组中第K大的数的方法总结

    [经典算法题]寻找数组中第K大的数的方法总结 责任编辑:admin 日期:2012-11-26   字体:[大 中 小] 打印复制链接我要评论   今天看算法分析是,看到一个这样的问题,就是在一堆数据 ...

随机推荐

  1. Spring Boot 企业级应用开发实战 刘伟东-2018年3月第一版

    Spring会自动搜索某些路径下的Java类 并将这些类注册微Bean实例,这样就省去了所有Bean都配置在XML的麻烦 Spring会适当地将显示指定路径下的的类全部注册微Spring Bean . ...

  2. 如何检测Windows中的横向渗透攻击

    一.前言 横向渗透攻击技术是复杂网络攻击中广泛使用的一种技术,特别是在高级持续威胁(Advanced Persistent Threats,APT)中更加热衷于使用这种攻击方法.攻击者可以利用这些技术 ...

  3. Active Directory渗透测试典型案例

    0x01 前言 我有几个客户在渗透测试之前来找我,说他们的系统安全做得非常好,因为他们的漏洞扫描显示没有严重的漏洞并且已准备好进行安全测试,这使我在15分钟内利用AD中的错误配置获得了域管理员权限. ...

  4. MYSQL中的时间类型

    时间上总共有五中表示方法:它们分别是 time.date.datetime.timestamp和year. time :  “hh:mm:ss”格式表示的时间值,格式显示TIME值,但允许使用字符串或 ...

  5. React 性能优化之组件动态加载(react-loadable)

    React 项目打包时,如果不进行异步组件的处理,那么所有页面所需要的 js 都在同一文件中(bundle.js),整个js文件很大,从而导致首屏加载时间过长. 所有,可以对组件进行异步加载处理,通常 ...

  6. 搭建前端监控系统(五)Nodejs怎么搭建消息队列

    怎样定位前端线上问题,一直以来,都是很头疼的问题,因为它发生于用户的一系列操作之后.错误的原因可能源于机型,网络环境,接口请求,复杂的操作行为等等,在我们想要去解决的时候很难复现出来,自然也就无法解决 ...

  7. Python之路(第四十二篇)线程相关的其他方法、join()、Thread类的start()和run()方法的区别、守护线程

    一.线程相关的其他方法 Thread实例对象的方法 # isAlive(): 返回线程是否活动的. # getName(): 返回线程名. # setName(): 设置线程名. ​ threadin ...

  8. kbmmw 中的Boyer-Moore算法

    kbmmw 5.10 版本中实现了一个非常好用的字符串搜索算法,即Boyer-Moore算法. 在用于查找子字符串的算法当中,BM(Boyer-Moore)算法是目前被认为最高效的字符串搜索算法, 它 ...

  9. linux shell的输出效果

    在linux系统命令行界面默认目录颜色是蓝色,在黑色底色上无法看清 原来效果图: 最终效果图: 大致步骤:1.复制配置文件到个人用户的根目录下2.修改配置文件中字体颜色的设置3.重新启动窗口,输入ls ...

  10. pip问题:ImportError: cannot import name main

    问题描述 今天使用pip安装python包的时候,提示可以升级到最新版的pip,然后就升级了pip,从8.1.1到19.0.3,结果,就出现了下面的问题,pip不能用了: Traceback (mos ...