首先我们需要了解什么是TopK问题,那就是给你一个一组数据,数据可能很少或者很多,让你找到前K小或者前K大的数据。当数据比较少的时候我们可以使用暴力解法,那就是直接对整个数据进行排序处理,然后取前K个元素那就是答案,但是当数据非常多的时候,效率也会变得相对比较慢。
以上所述,直接排序对数据量很大的场景是不太合适的,所以我们利用优先级队列来解决TopK问题,我们设想一下,我们要找前K大的数据,这时候我们的优先级队列要实现一个大堆还是一个小堆?答案是小堆,当我们把题目要求K个元素放入堆中之后,就形成了一个小堆,我们之后只要第K+1个和堆顶进行比较,比堆顶大的就把堆顶弹出,把新的元素放入堆中,以此类推,最后你会发现堆顶的元素就是第K大的元素,因为他是一个小堆,所以堆顶以下的元素都比堆顶元素大,所以你只要把这个堆里面的值打印出来那就是前K大的元素了。
以上就是TopK问题的整体思路,我们上面以取前K大的元素为例,我们如果要取前K小的元素,就模仿上面所讲,建一个大堆来进行处理,就能得到答案。
我们用一个例子来理解TopK问题(Java来解决):
找出数组中最小的K个数。
arr = [1,3,10,5,9,8,2], K = 3
我们期望得到的结果是:[1,2,3]
我们要找到前K小个数,所以我们这里建立一个大堆:
因为PriorityQueue默认是一个小堆,这时候我们需要传入比较器进行建立大堆的操作。
PriorityQueue<Integer> priorityQueue=new Pri