zoukankan      html  css  js  c++  java
  • [编程题] 基础:如何使用大顶堆和小顶堆找topN

    [编程题] 基础:如何使用大顶堆和小顶堆找topN

    需求

    (1)我们如何从一个链表或者数组中,找到第k大的数,或者前k大的数。使用小顶堆。(输出是从小到大排列的前K大的数)

    (2)我们如何从一个链表或者数组中,找到第k小的数,或者前k小的数(输出的堆是堆顶最大,其他不是序列顺序),使用大顶堆

    小顶堆

    找到数组中第K大的元素

    方法:需要找第K大,使用小顶堆。

    Java代码:

    package Demo11_堆;
    
    import java.util.PriorityQueue;
    
    /**
     * @author jiyongjia
     * @create 2020/7/26 - 11:27
     * @descp:
     */
    public class P1_小顶堆选出前K大 {
        //默认是小顶堆
        static int k=4;
        static PriorityQueue<Integer> queue;
        public static void main(String[] args) {
            queue = new PriorityQueue<Integer>(k);
            int[] arr = {1,3,5,2,6};
            //把数组元素放入到堆中
            for (int num:arr){
                P1_小顶堆选出前K大.add(num);
            }
    
        }
    
        //要求选出前k大的数
       public static void add(int val){
            if(queue.size()<k){
                queue.offer(val);
                //小顶堆的堆顶放的是已存在堆中的最下的数,如果有val比其最小的堆顶值大,说明堆中不是前k大的数,调整堆。
            }else if(queue.size()>=k && queue.peek()<val){
                queue.poll();
                queue.offer(val);
            }
           System.out.println("数组中第"+k+"大:"+queue.peek());  //数组中第4大:2
           System.out.println("堆:"+queue);   //堆:[2, 3, 5, 6]
        }
    }
    
    

    输出:第4大的元素是2,堆中的i情况是2 3 5 6

    image-20200726121613963

    大顶堆

    找到数组中第K小的元素

    方法:需要找第K小,使用大顶堆。

    注:要构造大顶堆的时候,是需要构造方法传入comparator比较器,compare方法的参数o2-o1表示大顶堆。o1-o2返回表示小顶堆,小顶堆也是默认的,可以无comparator。

    Java代码:

    package Demo11_堆;
    
    import java.util.Comparator;
    import java.util.Iterator;
    import java.util.PriorityQueue;
    
    /**
     * @author jiyongjia
     * @create 2020/7/26 - 11:54
     * @descp:
     */
    public class P2_大顶堆选出前K小 {
        static PriorityQueue<Integer> queue;
        static int k = 3;
        public static void main(String[] args) {
            queue = new PriorityQueue<Integer>(k, new Comparator<Integer>() {
                @Override
                public int compare(Integer o1, Integer o2) {
                    return o2-o1;  //小顶堆o1-o2,大顶堆o2-o1;
                }
            });
    
            int[] arr = {1,2,3,4,5,6,7,8};
            //把数组元素放入到堆中
            for (int num:arr){
                P2_大顶堆选出前K小.add(num);
            }
    
        }
    
        //要求选出前k小的数
        public static void add(int val){
            if(queue.size()<k){
                queue.offer(val);
                //大顶堆,堆顶放的是已存在堆中的最大的元素,如果存在val比堆中存在的最大元素小,说明堆中保存的不是前k小,去除堆顶,放入val
            }else if(queue.size()>=k && queue.peek()>val){
                queue.poll();
                queue.offer(val);
            }
            System.out.println("第k小的元素:"+queue.peek());
            System.out.println("堆中元素:"+queue);
    
        }
    }
    
    

    输出:

    image-20200726122033811

  • 相关阅读:
    POJ1239
    HDU 2829 四边形不等式优化
    返回数字二进制的最高位位数o(n)
    矩阵快速幂 模板
    HDU4718 The LCIS on the Tree(LCT)
    HDU4010 Query on The Trees(LCT)
    HDU3487 Play With Chains(Splay)
    CF444C DZY Loves Colors
    HDU4836 The Query on the Tree(树状数组&&LCA)
    HDU4831&&4832&&4834
  • 原文地址:https://www.cnblogs.com/jiyongjia/p/13379959.html
Copyright © 2011-2022 走看看