问题: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. MySQL基础-2

    目录 配置文件的使用 表的分类--数据库引擎 简单的表的增删改查(CRUD) 创建表的完整写法 Mysql中的数据类型 数字类型 字符串类型 枚举和集合 时间和日期 配置文件的使用 大家发现每次进入m ...

  2. 48.vue-awesome-swipe使用

    1.安装:npm install vue-awesome-swiper --save 2.局部引入: import "swiper/dist/css/swiper.css"; im ...

  3. Java 数组(一)定义与访问

    一.数组 1.容器概述    容器:是将多个数据存储到一起,每个数据称为该容器的元素. 2.数组概述  数组:数组就是存储数据长度固定的容器,保证多个数据的数据类型要一致. 数组特点: (1)数组是一 ...

  4. java实现表达式求值 (20 分)-------非递归版

    Dr.Kong设计的机器人卡多掌握了加减法运算以后,最近由学会了一些简单的函数求值.比如,它知道函数min(20, 23)的值是20, add(10, 98)的值是108等等.经过训练,Dr.Kong ...

  5. linux设备驱动程序-i2c(0)-i2c设备驱动源码实现

    (基于4.14内核版本) 为了梳理清楚linux内核中的i2c实现框架,从本文开始,博主将分几个章节分别解析i2c总线在linux内核中的形成过程.匹配过程.以及设备驱动程序源码实现. 在介绍linu ...

  6. [2019.05.09]Linux 学习笔记(3)

    最近的心得: CLI真好用,GUI就是渣渣 1. Bash 里面的命令是可以起别名的,起一个别名的方法是 alias [Alias]=[command] command可以是任意长的别名,比如 ali ...

  7. django最小程序开发流程

    1.建立工程 在工程目录下打开cmd,输入以下命令.其中mysite是项目名称. django-admin startproject mysite 命令运行完后,在该目录下会出现一个名为mysite的 ...

  8. Unable to load bean org.apache.struts2.dispatcher.multipart.MultiPartRequest

    Unable to load bean org.apache.struts2.dispatcher.multipart.MultiPartRequest (jakarta) 把commons-ileu ...

  9. 轻松学习之三——IMP指针的作用

    http://www.jianshu.com/p/425a39d43d16 可能大家一直看到有许多朋友在Runtime相关文章中介绍IMP指针的概念,那么IMP究竟有什么实际作用呢?让我们先从一个函数 ...

  10. Predicate Format String Syntax 与字面量

    字面量: 字符串:单引号或双引号扩起来: %@:系统自动添加,数字则自动去除@(): 无单双引号,系统做数字处理. Single or double quoting variables (or sub ...