zoukankan      html  css  js  c++  java
  • 简单的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;
    
        }
    }
  • 相关阅读:
    撤回本地的提交
    antd Table每列样式修改
    大数组拼树
    滑动加载
    数组合并去除重复内容
    获取前一周期日期
    js 对象根据value获取对应的key
    less git上传问题处理
    5G
    Linux怎么安装node.js
  • 原文地址:https://www.cnblogs.com/newpanderking/p/3952218.html
Copyright © 2011-2022 走看看