zoukankan      html  css  js  c++  java
  • 第k大的数,前k大的数

    1、排序后去出前k个,o(n*log(n))    如果k<log(n),可以考虑直接选择排序,因为只需要执行找到第k个就可以结束 o(n*k)

    2、o(nlog(k))快排把数分为了两个部分,所以考虑两个情况,如果大的部分的个数>k,说明只要继续在大的部分找就可以了,

                                                                   如果大的部分的个数<k,先把这些数取了,然后继续在小的部分里面找剩下的数(k-大的部分的个数)就可以了。

    3、o(nlog((maxv-minv)/delta)),平均为o(nlogn)   转化为找第k个,  假设最大的数为maxv,最小的为minv,那么第k个数必然在[minv,maxv]这个区间中,每次二分这个区间,设mid的数为s,看数组a中比s大的数有没有k大来调整二分,就最后可以得到了。

         如果文件太大,每次统计midv的个数都需要读一次文件,完成一个循环后,把新的区间存入一个新的文件,然后直到新的文件可以放入内存。

    while(maxv- minv > delta)
    {
        midv = minv + (maxv - minv)*0.5;
        if(f(a,N,midv) >= k) minv = midv;
        else maxv = midv;
    }
    
    f(a,N,midv)是找出a数组中比midv大的数的个数

    4、维护一个k个数的小顶堆,遍历数组a,然后每次更新小顶堆即可  o(nlog(k))     实际就是堆排序

    if(x > h[0])
    {
        h[0] = x;
        p,q;
        p = 0;
        while(p < k)
        {
             q = 2*p + 1if(q >= k )break;
             
             if( (q<k-1) && (h[q+1] < h[q]) ) q = q + 1;
             
             if(h[q] < h[p])
             {
                   swap(h[q],h[p]);
                   p = q;
             }
             else break;
        }
    }

         如果k太大不能一次装入内存k个数的堆,那么选一个可以装入内存的数s,第一次找s个,然后找s个。。。直到s*i >k即可。。。但这样要读的数组a的次数就必须增加了。

  • 相关阅读:
    SpringBoot JdbcTemplate多数据源
    SpringBoot Mybatis多数据源
    SpringBoot 配置文件2
    SpringBoot 配置文件1
    SpringBoot 日志配置
    乌镇行
    防火墙
    PL/SQL查询结果窗口太小且显示不完全
    python 列表解析
    HTML
  • 原文地址:https://www.cnblogs.com/juandx/p/4057118.html
Copyright © 2011-2022 走看看