堆排序应用之topK问题
题目:求海量数据(正整数)按逆序排列的前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问题的更多相关文章
- [151225] Python3 实现最大堆、堆排序,解决TopK问题
参考资料: 1.算法导论,第6章,堆排序 堆排序学习笔记及堆排序算法的python实现 - 51CTO博客 堆排序 Heap Sort - cnblogs 小根堆实现优先队列:Python实现 -cn ...
- PHP实现堆排序
经验 工作了,面试我工作这家公司时被技术面打击得不行,因为自己的数据结构等基础学得实在太差,虽然原来是想做设计师的说...不过看在PHP写得还凑合的份上能来实习了,但还是决心恶补一下基础. 其实自己之 ...
- Java面试宝典系列之基础排序算法
本文就是介绍一些常见的排序算法.排序是一个非常常见的应用场景,很多时候,我们需要根据自己需要排序的数据类型,来自定义排序算法,但是,在这里,我们只介绍这些基础排序算法,包括:插入排序.选择排序.冒泡排 ...
- leetcode算法总结
算法思想 二分查找 贪心思想 双指针 排序 快速选择 堆排序 桶排序 搜索 BFS DFS Backtracking 分治 动态规划 分割整数 矩阵路径 斐波那契数列 最长递增子序列 最长公共子系列 ...
- Leedcode算法专题训练(排序)
排序 快速排序 用于求解 Kth Element 问题,也就是第 K 个元素的问题. 可以使用快速排序的 partition() 进行实现.需要先打乱数组,否则最坏情况下时间复杂度为 O(N2). 堆 ...
- [数据结构]——堆(Heap)、堆排序和TopK
堆(heap),是一种特殊的数据结构.之所以特殊,因为堆的形象化是一个棵完全二叉树,并且满足任意节点始终不大于(或者不小于)左右子节点(有别于二叉搜索树Binary Search Tree).其中,前 ...
- 堆的源码与应用:堆排序、优先队列、TopK问题
1.堆 堆(Heap))是一种重要的数据结构,是实现优先队列(Priority Queues)首选的数据结构.由于堆有很多种变体,包括二项式堆.斐波那契堆等,但是这里只考虑最常见的就是二叉堆(以下简称 ...
- 关于堆排序和topK算法的PHP实现
问题描述 topK算法,简而言之,就是求n个数据里的前m大个数据,一般而言,m<<n,也就是说,n可能有几千万,而m只是10或者20这样的两位数. 思路 最简单的思路,当然是使用要先对这n ...
- python堆排序实现TOPK问题
# 构建小顶堆跳转def sift(li, low, higt): tmp = li[low] i = low j = 2 * i + 1 while j <= higt: # 情况2:i已经是 ...
随机推荐
- vertx模块HAManager高可用
HAManager public HAManager(VertxInternal vertx, DeploymentManager deploymentManager, ClusterManager ...
- 如何进行PDF页码编排,如何调整PDF页码顺序
PDF文件的页码顺序如何进行调整?许多小伙伴们都不知道,我们在编辑的时候只知道PDF文件的编辑方法,但是调整页码的顺序我们或许不会,但是如何去进行操作呢?看小编的方法吧!如果我们想要修改PDF文件中的 ...
- css 自制一些小特效
Github地址 位于gh-pages分支上 https://github.com/a1115040996/MyHTML/ 3D 卡片特效 地址: https://a1115040996.github ...
- Python学习笔记十一
1. 协程 并发的解决方案: 多进程 多线程 什么叫并发:看起来同时进行 如何实现并发:切换+保存状态 进程线程都是由操作系统调度的 协程:单线程下实现的并发,应用程序级别的切换, ...
- 2018-2019-2 网络对抗技术 20165206 Exp4 恶意代码分析
- 2018-2019-2 网络对抗技术 20165206 Exp4 恶意代码分析 - 实验任务 1系统运行监控(2分) (1)使用如计划任务,每隔一分钟记录自己的电脑有哪些程序在联网,连接的外部IP ...
- OpenCV-Python:K值聚类
关于K聚类,我曾经在一篇博客中提到过,这里简单的做个回顾. KMeans的步骤以及其他的聚类算法 K-均值是因为它可以发现k个不同的簇,且每个簇的中心采用簇中所含值的均值计算 其他聚类算法:二分K-均 ...
- java web项目部署到tomcat 8.5 此驱动程序不支持 Java Runtime Environment (JRE) 1.8 版。请使用支持 JDBC 4.0 的 sqljdbc4.jar 类库
1:项目使用的是jre1.8版本. 2:服务器 apache-tomcat-8.5.23 报错如下: 严重 [com.mchange.v2.async.ThreadPoolAsynchronousRu ...
- 安装SSL证书 and 根域名跳转www域名
1.安装自签证书 自签证书也就是不被公网认可的证书,可在局域网内进行签名认证,其12306也是自签证书,通过证书+nginx代理web服务器 可以实现https连接 一.使用OpenSSL创建证书 ...
- scss/less语法以及在vue项目中的使用(转载)
1.scss与less都是css的预处理器,首先我们的明白为什么要用scss与less,因为css只是一种标记语言,其中并没有函数变量之类的,所以当写复杂的样式时必然存在局限性,不灵活,而scss与l ...
- UOJ#374. 【ZJOI2018】历史 贪心,LCT
原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ374.html 题解 想出正解有点小激动. 不过因为傻逼错误调到自闭.不如贺题 首先我们考虑如何 $O(n ...