简单的topK问题

/************************************************************************/
/*
求一组数据中的top(K)问题,这是一个经典的top(K)问题。
分析:
方法一:如果数据量不大,那么最常用的方法就是排序从大大小,然后找出前k个数据。
比较高效率的排序算法,如快排,堆排序等,总体时间复杂度为 O(N*log2(N))+O(K)=O(N*log2(N))
或是直接用部分排序算法,如选择排序,直接找出前K个元素,时间复杂度为O(N*K),
至于O(N*log2(N)) 还是O(N*K)效率高,看K的取值,若K<log2(N)那么部分排序效率高。

方法二:
如果数据量非常大,不能够加载到内存中,这就成了一个海量数据问题。求其中的top(K)
就是我们所求的前K个大的数据。
这样考虑,我们用一个长度为K大小的数组存储前k个数据,然后经过一次扫描数据,每次
扫描一个数据,和数据中最小的数据比较,如果小于这个数据,继续下一个数据扫描,如果
大于这个数据,那么就替换掉数组中最小的那个数据。这样所消耗的时间效率为O(N*K)
进一步,我们可以用容量为K大小的最小堆来存储前K个数据,如果我们新扫描的数据小于堆顶
的数据,那么我们就替换最小堆的堆顶数据,调整最小堆形成新的最小堆。

最小堆可以用一个长为K大小的数组h模拟,对于结点h[i],其中父节点为h[i/2],
儿子节点为:h[2*i+1]和h[2*i+2];

*/
/************************************************************************/

/*
n为要判断的数字,h为最小堆,k为topk 即最小堆维持的大小。
*/
void topK(int n,int *h,int K)
{
    if(n<h[0])return;
    int p = 0;
    int q = 0;
    h[0] = n;
    while(p < K)
    {
        q = 2*p +1;
        if (q >= K) break;
        if (h[p] < h[q] && h[p] < h[q+1])break;
        if (h[2*p+1] > h[2*p+2] ) q++;
        int tem = h[q];
        h[q] = h[p];
        h[p] = tem;
        p = q;

    }
}
时间: 2024-10-04 03:14:25

简单的topK问题的相关文章

计算机程序的思维逻辑 (47) - 堆和PriorityQueue的应用

45节介绍了堆的概念和算法,上节介绍了Java中堆的实现类PriorityQueue,PriorityQueue除了用作优先级队列,还可以用来解决一些别的问题,45节提到了如下两个应用: 求前K个最大的元素,元素个数不确定,数据量可能很大,甚至源源不断到来,但需要知道到目前为止的最大的前K个元素.这个问题的变体有:求前K个最小的元素,求第K个最大的,求第K个最小的. 求中值元素,中值不是平均值,而是排序后中间那个元素的值,同样,数据量可能很大,甚至源源不断到来. 本节,我们就来探讨如何解决这两个

Papers about DL

Reading some papers about DL Reading some papers about DL SegNet A Deep Convolutional Encoder-Decoder Architecture for Image Segmentation Encoder network Decoder network Training Analysis 个人想法 Do Convnets learn Correspondence Ideas Methods 1 Method 2

(TopkOnJstorm)第二周工作报告:2014-07-14~2014-07~20

本周的工作分两个部分 一:搭建JStorm环境(三个机器组成的集群) 由于微软AZure的虚拟机还没有申请下来,我先在实验室的环境下搭建了 1. 搭建Zookeeper集群 a) 下载Zookeeper的3.4.5版本,解压至/xxx/xxx/zookeeper-3.4.5 b) 配置环境变量(在~/.bashrc) export ZOOKEEPER_HOME=/xxx/xxx/zookeeper-3.4.5 export PATH=$PATH:$HOME/bin:$ZOOKEEPER_HOME

Topk引发的一些简单的思考

软件工程课程的一个题目:写一个程序,分析一个文本文件中各个词出现的频率,并且把频率最高的10个词打印出来.文本文件大约是30KB~300KB大小. 首先说一下这边的具体的实现都是在linux上实现的.没有大型IDE的性能检测.其实30KB还不是瞬间的事情,基于语言和一些简单的策略.所以在后面可能会尝试考虑增加文件大小到G级,然后发生的东西.我只能是从简单的原理研究.至于调试我只能写个简单的shell来自己检测一下.嗯,就这样吧.能力还是有点小白,特别是看了v_JULY_v 的海量数据处理http

MapReduce TopK问题实际应用

一:背景 TopK问题应该是海量数据处理中应用最广泛的了,比如在海量日志数据处理中,对数据清洗完成之后统计某日访问网站次数最多的前K个IP.这个问题的实现方式并不难,我们完全可以利用MapReduce的Shuffle过程实现排序,然后在Reduce端进行简单的个数判断输出即可.这里还涉及到二次排序,不懂的同学可以参考我之前的文章. 二:技术实现 #我们先来看看一条Ngnix服务器的日志: [java] view plain copy 181.133.250.74 - - [06/Jan/2015

协同过滤介绍和简单推荐系统的实现

本文引自http://blog.csdn.net/database_zbye/article/details/8664516 本文介绍推荐系统.协同过滤思想,两种基本的相似度衡量,并用python实现.最后就MovieLens数据集上作出简单的推荐. 一.相关知识 (1)推荐系统 如今,推荐系统已经在多方面得到应用,例如淘宝.当当.亚马逊等网站的商品推荐.而个性化推荐系统则是通过发掘用户的兴趣爱好,作出针对性的推荐.个性化推荐的方法较多,最常用的是协同过滤方法,而本文主要讲的也是基于协同过滤的个

《人民的名义》---简单的文本分析

我们都知道进行自然语言处理的第一步就是分词,下面使用jieba模块对最近比较热的电视剧<人民的名义>进行分词,并对它进行一些简单的文本分析. 一.jieba模块中常用的方法说明(github): 1.分词: jieba.cut 方法接受三个输入参数: 需要分词的字符串:cut_all 参数用来控制是否采用全模式:HMM 参数用来控制是否使用 HMM 模型 jieba.cut_for_search 方法接受两个参数:需要分词的字符串:是否使用 HMM 模型.该方法适合用于搜索引擎构建倒排索引的分

排序中topK那点事(转)

问题描述:有 N (N>1000000)个数,求出其中的前K个最小的数(又被称作topK问题). 这类问题似乎是备受面试官的青睐,相信面试过互联网公司的同学都会遇到这来问题.下面由浅入深,分析一下这类问题. 思路1:最基本的思路,将N个数进行完全排序,从中选出排在前K的元素即为所求.有了这个思路,我们可以选择相应的排序算法进行处理,目前来看快速排序,堆排序和归并排序都能达到O(NlogN)的时间复杂度.当然,这样的答案也是无缘offer的. 思路2:可以采用数据池的思想,选择其中前K个数作为数据

Mapreduce TopK

思想比较简单,就是每个通过map来获取当前的数据块中的的topk个数据,然后将他们以相同的key值放到reduce中,最后通过reduce来对这n*k个数据排序并获得topk个数据.具体的就是建立一个k个大小的数组,一开始初始化为都是100(假定这里的100是最大的数),然后往里面插数据小的数据即可. PS:有几个小细节以及当时写代码的时候出错的地方. 1 map和reduce都是在每个键值对来的时候会被调用.当时觉得应该把这k的数组放在哪,以及怎么初始化.如果放在map方法里面,那每次都会被初