zoukankan      html  css  js  c++  java
  • 排序中topK那点事(转)

    问题描述:有 N (N>1000000)个数,求出其中的前K个最小的数(又被称作topK问题)。

     

    这类问题似乎是备受面试官的青睐,相信面试过互联网公司的同学都会遇到这来问题。下面由浅入深,分析一下这类问题。

     

    思路1:最基本的思路,将N个数进行完全排序,从中选出排在前K的元素即为所求。有了这个思路,我们可以选择相应的排序算法进行处理,目前来看快速排序,堆排序和归并排序都能达到O(NlogN)的时间复杂度。当然,这样的答案也是无缘offer的。

     

    思路2:可以采用数据池的思想,选择其中前K个数作为数据池,后面的N-K个数与这K个数进行比较,若小于其中的任何一个数,则进行替换。这种思路的算法复杂度是O(N*K),当答出这种算法时,似乎离offer很近了。

     

    有没有算法复杂度更低的方法呢?

     

    从思路2可以想到,剩余的N-K个数与前面K个数比较的时候,是顺序比较的,算法复杂度是K。怎么在这方面做文章呢? 采用的数据结构是堆。

     

    思路3:大根堆维护一个大小为K的数组,目前该大根堆中的元素是排名前K的数,其中根是最大的数。此后,每次从原数组中取一个元素与根进行比较,如小于根的元素,则将根元素替换并进行堆调整(下沉),即保证大根堆中的元素仍然是排名前K的数,且根元素仍然最大;否则不予处理,取下一个数组元素继续该过程。该算法的时间复杂度是O(N*logK),一般来说企业中都采用该策略处理topK问题,因为该算法不需要一次将原数组中的内容全部加载到内存中,而这正是海量数据处理必然会面临的一个关卡。如果能写出代码,offer基本搞定。

     

    还有没有更简单的算法呢?答案是肯定的。

     

    思路4:利用快速排序的分划函数找到分划位置K,则其前面的内容即为所求。该算法是一种非常有效的处理方式,时间复杂度是O(N)(证明可以参考算法导论书籍)。对于能一次加载到内存中的数组,该策略非常优秀。如果能完整写出代码,那么相信面试官会对你刮目相看的。

     

    下面,给出思路4的Python代码:

    def partition(data,start,end):
        if len(data)==1:
            return 0
        small=start
        p=small+1
        while p<=end:
            if data[p]<data[start]:
                small+=1
                data[p],data[small]=data[small],data[p]
            p+=1
        data[start],data[small]=data[small],data[start]
        return small
    
    def topk(data,k):
        if k==0:
            return None
        if len(data)<=k:
            return data
        left=0
        right=len(data)-1
        s=partition(data,left,right)
        while s+1!=k: #下标加1才能与前k的k进行比较
            if s+1>k:
                right=s-1
            if s+1<k:
                left=s+1
            s=partition(data,left,right)
        
        return data[:k]
     
  • 相关阅读:
    IIS 之 未能加载文件或程序集“IBM.Data.DB2”或它的某一个依赖项。试图加载格式不正确的程序。
    WebService 之 身份验证
    MVC 之 属性详解
    绕过Web授权和认证之篡改HTTP请求
    跨站点脚本编制-XSS 描述及解决方法
    CSRF(跨站请求伪造攻击)漏洞详解
    HTTP.SYS 远程执行代码漏洞分析(MS15-034 )
    Socket 之 传值方式
    GET 和 POST的区别
    Gdb调试多进程程序
  • 原文地址:https://www.cnblogs.com/gczr/p/7007592.html
Copyright © 2011-2022 走看看