Top-K问题
使用背景
生活中,我们经常要给某些数据排序,比如美团上某一类型的外卖在一地区排名,拿我生活的地方举例,陕西排名前十的凉皮…。如果觉得不够亲切,拿王者荣耀来举例,陕西省最强李白,陕西省十强李白,陕西省百强李白。这时候,我们只能看到前一百名,后面的排名不重要,我们不需要给陕西所有的李白玩家都排名,用堆来解决再合适不过了。下面给出解决思路。
并且面试时,这个问题是一个常考题。
解决问题思路及代码实现
思路1
堆排序,冒泡排序,等等排序算法。
优点:
- 所有的数据都进行了排序,想要第多少名都可以。
缺点:
- 时间复杂度高,有时候我们并不需要全部排名,
- 只要前十个数据等等
排序算法代码就不多赘述了,大家可以自己百度找找。
思路2
对所有数据建堆,堆顶即最值,建堆一次选出一个最值,取堆顶保存,对剩下的数据再建堆,算上第一次建堆,求k个数据,建k次堆,保存k个堆顶。
优点:
- 较为优秀的解决办法,但有缺陷
缺点:
- 当数据量很大时,建堆内存不够怎么办?
- 要取的数据多,k值很大建堆次数也上升。
代码:
思路3
第一步: 求最小的前k个数,我们就建立一个含有k个数据的大堆(为什么建大堆呢?求最小值不是应该建立小堆吗?稍后讲解),
第二步:然后将剩余的数据和这个堆的堆顶比较,如果小于堆顶,交换数据,向下调整入堆,直到所有数据比较完毕。
第三步:将这个k个数据的大堆进行堆排序,所得结果即为所求。