最小的 K 个数


输入 n 个整数,找出其中最小的 K 个数。例如输入 4,5,1,6,2,7,3,8 这 8 个数字,则最小的 4 个数字是 1,2,3,4


解题思路

使用任意一种排序算法即可,得到有序的序列后,就可以直接取出目标值了。但如果遇到海量数据时,如果算法选择不当有可能会崩溃,这里推荐两种比较好的排序算法。

第一种:改良后的冒泡排序算法

使用冒泡排序思想,不需要全部遍历一次,因为题目只要求前 K 个数,所以最外层循环 K 次就好了。

import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
        ArrayList<Integer> list = new ArrayList<>();
        if(k > input.length) {
            return list;
        }
        for(int i = 0; i < k; i++) {
            for(int j = 0; j < input.length - i - 1; j++) {
                if(input[j] < input[j + 1]) {
                    int temp = input[j];
                    input[j] = input[j + 1];
                    input[j + 1] = temp;
                }
            }
            list.add(input[input.length - i - 1]);
        }
        return list;
    }
}

还可以考虑使用堆排序。堆排序的空间复制度仅为 O(1),并且时间复杂度稳定为 O(nlogN),适合处理海量数据。对应堆的实现,我们可以使用 Java 为我们提供的优先级队列 PriorityQueue

import java.util.PriorityQueue;
import java.util.ArrayList;
import java.util.Comparator;
public class Solution {
    public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
        ArrayList<Integer> list = new ArrayList<>();
        int length = input.length;
        if(k > length || k <= 0) {
            return list;
        }
        PriorityQueue<Integer> maxHeap = new PriorityQueue<>(k, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2.compareTo(o1);
            }
        });
        for(int i = 0; i < length; i++) {
            if(maxHeap.size() != k) {
                maxHeap.offer(input[i]);
            } else if(maxHeap.peek() > input[i]){
                maxHeap.poll();
                maxHeap.offer(input[i]);
            }
        }
        for (Integer integer : maxHeap) {
            list.add(integer);
        }
        return list;
    }
}

原文地址:https://www.cnblogs.com/Yee-Q/p/13821390.html