问题:从比较多的数据中找出最大的K个数。
该问题主要有以下几种解法:
1.直接进行排序。堆排序和快速排序都是比较好的选择,在时间为N*lgN的时间开销下完成排序然后再选择前K个数即为最大的K。在这里可以讨论一下
K的大小,如果K<lgN的话我们可以用内部排序中的选择排序,对整个数据遍历K遍得到最大的K个数。
2.如果只要求找出最大的K个数,而对K个数顺序没有要求,那么可以对这一堆数据进行改良的快速排序:首先选择数据中部的元素mid,来一趟快速排
序,这样会产生两个集合Sa和Sb,其中Sa中的元素都比mid大,Sb则相反。这个时候如果Sa.length<K,则在Sa中继续查找最大个K,否则在Sb中查找
K-Sa.length最大数,如此循环下去当Sa.length==K可以得到结果。
3.如果知道该数据集的最大值和最小值,则用二分查找进行找出第K大的数,令mid=(max+min)/2,反复调用count(arr,mid)得到大于mid的数据个数,如
果大于K则在(min,mid)中查找,反之在(mid,max)中查找。最后得到的即为第K大的数,然后遍历一遍整个数据就得到了最大K个数,时间复杂度为
O(N*lgN)。
4.如果带查的数据非常大如100亿,则可以用利用前K个数组成最小堆,然后分次将数据读入内存遍历,并更新堆。或者针对数据特点如果是整数,先
对数据依次Hash操作,将数据最高位分组,然后由大到小统计。统计出现次数最多的K个数也可以利用相关分治算法,将大问题变成小问题加以解决。
- 首先用到了分类讨论的思想,数据是整型、浮点型和串型处理方法有区别,数据的分布也要考虑,针对不同的问题给出不同的解法。
- 综合比较各个算法的性能以及如何对其进行优化,例如当数据基本有序时,快速排序性能就会退化为冒泡排序,因为每一趟快速排序没有将问题的规模减半,只是消掉了常数个逆序数。
- 处理的数据量很大时内部排序就不适用了,要用上外部排序。