最小的 K 个数
题目描述:输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4。
PS:与牛客相同!
1. 分析
对于n个整数中最小的K个数的查找,可以使用各种排序算法:冒泡/堆排/快排/希尔排序等等。
将此n个整数从小到大排序之后,前k个数就是所求的结果。
但是当原数组中的数据顺序不可修改,并且n的值过于大的时候,各种排序算法要将n个数加载到内存中,即:如果是海量数据中查找出最小的k个数,那么这种办法是效率很低的。
接下来介绍另外一种算法:创建一个大小为k的数组,遍历n个整数,如果遍历到的数小于大小为k的数组的最大值,则将此数与其最大值替换。由于每次都要拿n个整数和数组中的最大值比较,所以选择大根堆这一数据结构(大家要分清楚大根堆这一数据结构和堆排序之间的区别:堆排序是在大根堆这一数据结构上进行排序的一种排序算法,一个是数据结构,一个是算法)
2. 代码
另一种:用大根堆保存这 k 个数,每次只和堆顶比,如果比堆顶小,删除堆顶,新数入堆。
1 import java.util.*; 2 3 public class Solution { 4 public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) { 5 ArrayList<Integer> result = new ArrayList<>(); 6 int length = input.length; 7 if(k <= 0 || k > length) { 8 return result; 9 } 10 PriorityQueue<Integer> maxHeap = new PriorityQueue<Integer> (k, new Comparator<Integer>() { 11 @Override 12 public int compare(Integer o1, Integer o2) { 13 return o2.compareTo(o1); 14 } 15 }); 16 for(int i = 0; i < length; i++) { 17 if(maxHeap.size() != k) { 18 maxHeap.offer(input[i]); 19 } else if(maxHeap.peek() > input[i]) { 20 Integer temp = maxHeap.poll(); 21 temp = null; 22 maxHeap.offer(input[i]); 23 } 24 } 25 for(Integer integer : maxHeap) { 26 result.add(integer); 27 } 28 return result; 29 } 30 }