题目:求海量数据(正整数)按逆序排列的前k个数(topK),因为数据量太大,不能全部存储在内存中,只能一个一个地从磁盘或者网络上读取数据,请设计一个高效的算法来解决这个问题。 第一行用户输入K,代表要求得topK  随后的N(不限制)行,每一行是一个整数代表用户输入的数据 直到用户输入-1代表输入终止 请输出topK,空格分割。

思路:先开辟一个K大小的数组arr,然后读取K个数据存储到数组arr,读到K+1的时候,如果arr[K+1]小于arr中最小的值,那么就丢掉不管,如果arr[K+1]大于arr中最小的值,那么就把arr[K+1]和数组中最小的值进行交换,然后再读取K+2个数。这样就能解决这个问题。但是这个算法复杂度为K+(N-K)*K,K可以忽略不计,所以时间复杂度为O(KN)。那这个代码很容易就写出来。假如题目要求用到NlgK的时间复杂度,那么这里就需要使用堆这种数据结构来解决问题,而且还是小顶堆。具体思想还是和数组一样。

代码:

 import java.util.Arrays;
import java.util.Scanner; public class TopK { static int[] heap;
static int index = 0;
static int k; public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
k = scanner.nextInt();
heap = new int[k];
int x = scanner.nextInt();
while(x!=-1){
deal(x); // 处理x
x = scanner.nextInt();
}
System.out.println(Arrays.toString(heap));
} /**
* 如果数据量小于等于k,直接加入堆中
* 等于k的时候,进行堆化
* @param x
*/
private static void deal(int x) {
if (index<k) {
heap[index++] = x;
if (index==k) {
// 堆化
makeMinHeap(heap);
System.out.println(Arrays.toString(heap));
}
}else if (heap[0]<x) {
heap[0] = x;
MinHeapFixDown(heap, 0, k);
System.out.println(Arrays.toString(heap));
}else {
System.out.println(Arrays.toString(heap));
}
}
static void makeMinHeap(int[] A){
int n = A.length;
for(int i = n/2-1;i>=0;i--){
MinHeapFixDown(A,i,n);
}
} private static void MinHeapFixDown(int[] A, int i, int n) {
// 找到左右孩子
int left = 2 * i + 1;
int right = 2 * i + 2 ;
// 左孩子已经越界,i就是叶子节点
if (left>=n) {
return ;
}
// min 指向了左右孩子中较小的那个
int min = left;
if (right>=n) {
min = left;
}else {
if (A[right]<A[left]) {
min = right;
}
}
// 如果A[i]比两个孩子都要小,不用调整
if (A[i]<=A[min]) {
return ;
}
// 否则,找到两个孩子中较小的,和i交换
int temp = A[i];
A[i] = A[min];
A[min] = temp;
// 小孩子那个位置的值发生了变化,i变更为小孩子那个位置,递归调整
MinHeapFixDown(A, min, n);
} }

结果:

  

总结:partition和堆都能解决顺序统计量问题,堆更适用于海量数据流,适用于不能全部存储在内存中的数据,相当于实时数据流,而partition适用于能够一次加载到内存的数组。

堆排序应用之topK问题的更多相关文章

  1. [151225] Python3 实现最大堆、堆排序,解决TopK问题

    参考资料: 1.算法导论,第6章,堆排序 堆排序学习笔记及堆排序算法的python实现 - 51CTO博客 堆排序 Heap Sort - cnblogs 小根堆实现优先队列:Python实现 -cn ...

  2. PHP实现堆排序

    经验 工作了,面试我工作这家公司时被技术面打击得不行,因为自己的数据结构等基础学得实在太差,虽然原来是想做设计师的说...不过看在PHP写得还凑合的份上能来实习了,但还是决心恶补一下基础. 其实自己之 ...

  3. Java面试宝典系列之基础排序算法

    本文就是介绍一些常见的排序算法.排序是一个非常常见的应用场景,很多时候,我们需要根据自己需要排序的数据类型,来自定义排序算法,但是,在这里,我们只介绍这些基础排序算法,包括:插入排序.选择排序.冒泡排 ...

  4. leetcode算法总结

    算法思想 二分查找 贪心思想 双指针 排序 快速选择 堆排序 桶排序 搜索 BFS DFS Backtracking 分治 动态规划 分割整数 矩阵路径 斐波那契数列 最长递增子序列 最长公共子系列 ...

  5. Leedcode算法专题训练(排序)

    排序 快速排序 用于求解 Kth Element 问题,也就是第 K 个元素的问题. 可以使用快速排序的 partition() 进行实现.需要先打乱数组,否则最坏情况下时间复杂度为 O(N2). 堆 ...

  6. [数据结构]——堆(Heap)、堆排序和TopK

    堆(heap),是一种特殊的数据结构.之所以特殊,因为堆的形象化是一个棵完全二叉树,并且满足任意节点始终不大于(或者不小于)左右子节点(有别于二叉搜索树Binary Search Tree).其中,前 ...

  7. 堆的源码与应用:堆排序、优先队列、TopK问题

    1.堆 堆(Heap))是一种重要的数据结构,是实现优先队列(Priority Queues)首选的数据结构.由于堆有很多种变体,包括二项式堆.斐波那契堆等,但是这里只考虑最常见的就是二叉堆(以下简称 ...

  8. 关于堆排序和topK算法的PHP实现

    问题描述 topK算法,简而言之,就是求n个数据里的前m大个数据,一般而言,m<<n,也就是说,n可能有几千万,而m只是10或者20这样的两位数. 思路 最简单的思路,当然是使用要先对这n ...

  9. python堆排序实现TOPK问题

    # 构建小顶堆跳转def sift(li, low, higt): tmp = li[low] i = low j = 2 * i + 1 while j <= higt: # 情况2:i已经是 ...

随机推荐

  1. LoadRunner结果分析与生成报告

    启动Analysis会话 1.打开HP LoadRunner2.打开LoadRunner Analysis在LoadRunner Analysis选项卡中单击分析负载测试3.打开Analysis会话文 ...

  2. python 对Excel表格的读取

    import xlrd flbrd = "D:\\考勤系统.xlsx" ws = xlrd.open_workbook(flbrd) # 获取所有sheet名字:ws.sheet_ ...

  3. Linux telnet安装

    为什么需要telnet? telnet就是查看某个端口是否可访问.我们在搞开发的时候,经常要用的端口就是 8080.那么你可以启动服务器,用telnet 去查看这个端口是否可用. Linux cent ...

  4. Filebeat+Kafka+Logstash+ElasticSearch+Kibana搭建完整版

    1. 了解各个组件的作用 Filebeat是一个日志文件托运工具,在你的服务器上安装客户端后,filebeat会监控日志目录或者指定的日志文件,追踪读取这些文件(追踪文件的变化,不停的读) Kafka ...

  5. [转] 如何设置双网卡同时连接内网外网_bpao_新浪博客

    已剪辑自: http://blog.sina.com.cn/s/blog_5d3e229c0100skwe.html 如何设置双网卡同时连接内网外网 . 通过无线网络连接外网,确保连接成功后开始第二步 ...

  6. sql server按月份,按项目号展开表格

    原始数据: 01 RD21 6495.411402 RD21 87.43604 RD21 101.718405 RD21 1.538401 RD25 7803.303709 RD25 106.8375 ...

  7. netty编程一:快速入门

    服务器端编程 第一步:maven 依赖 netty-all.jar,详情参考文章最后的maven依赖 第二步:创建服务端的NIO线程组EventLoopGroup: EventLoopGroup bo ...

  8. jquery.string.js

    /** * jquery.string - Prototype string functions for jQuery * version: 1.1.0 * (c) 2008-2011 David E ...

  9. ImCash:第一个集多功能于一身的数字资产平台

    Web2.0时代,去中心化开始被社会各界人士所知晓,随着网络时代的不断发展,去中心化概念慢慢得到了社会各界的追捧.行业巨头控制.算法运行干扰.大数据的不良利用.跨款平台支付的不便都在一定程度上对用户的 ...

  10. 第六届Code+程序设计网络挑战赛

    弹指能算(easy)模式只做出一道签到题,还WA了一发,我好菜啊啊啊啊...虽然我菜,但是比赛体验一点都不好,服务器老是崩. 比赛链接:https://moocoder.xuetangx.com/de ...