zoukankan      html  css  js  c++  java
  • 基于PriorityQueue(优先队列)解决TOP-K问题

    TOP-K问题是面试高频题目,即在海量数据中找出最大(或最小的前k个数据),隐含条件就是内存不够容纳所有数据,所以把数据一次性读入内存,排序,再取前k条结果是不现实的。

    下面我们用简单的Java8代码去解决TOP-K问题。为了使主要的逻辑更加清晰,去掉了一些如参数合法性检查等非关键代码。

    PriorityQueue(优先队列)是JDK1.5开始提供的,主要作者包括大名鼎鼎的纽约大学教授Doug Lea,他也是Java JUC包的鼻祖哦。

    PriorityQueue相当于一个堆(默认为小根堆,如果想要创建大根堆,那么在创建PriorityQueue时应指定为逆序,代码如下)

    new PriorityQueue<>(maxSize, Comparator.reverseOrder());

    下面我们就以默认的小根堆去解决TOP-K问题(小根堆用于解决前k个最大值,而大根堆用于解决前k个最小值)

    class FixSizedPriorityQueue {//自定义固定长度(k)的优先队列,因此可以解决Top-k问题
        PriorityQueue<Integer> queue;
        int k;
    
        public FixSizedPriorityQueue(int k) {
            this.k = k;
            this.queue = new PriorityQueue<>(k);
        }
    
        public void add(Integer e) {
            if (queue.size() < k) { //当前队列元素个数不足k个时,直接添加
                queue.add(e);
            } else { //超出k个时
                if (e.compareTo(queue.peek()) > 0) {// 如果新元素大于了堆顶元素,说明新元素应替换掉当前堆顶元素
                    queue.poll();
                    queue.add(e);
                }
            }
        }
    }
    public class Main {
    
        public static void main(String[] args) {
    
            final FixSizedPriorityQueue pq = new FixSizedPriorityQueue(10);
            Random random = new Random();
            random.ints(100, 0, 1000).forEach(pq::add);//产生100个0-1000的随机数,并加入自定义的定长优先队列
            while (!pq.queue.isEmpty()) {
                System.out.print(pq.queue.poll() + ", ");//不断取出堆顶元素,由于本例是小根堆,因此会从小到大打印出前10大的值
            }
        }
    }
  • 相关阅读:
    《小学生四则运算题卡》—— —— 毛锦媛
    《个人软件开发流程》——毕雷
    《个人软件开发流程》——东措
    《个人软件开发流程》——梁光姣
    《个人软件开发流程》——王从容
    《个人软件开发流程》——魏胜阳
    《个人软件开发流程》——申同燕
    《个人软件开发流程》——毛锦媛
    计应193第一组小学生做题软件——游晓
    计应193第一组小学生做题软件——段杏娜
  • 原文地址:https://www.cnblogs.com/flamestudio/p/12000151.html
Copyright © 2011-2022 走看看