方法1: 用大根堆维护k个最小值。O(nlogk)

import java.util.ArrayList;
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Queue;

public class Solution {
    public ArrayList<Integer> GetLeastNumbers_Solution(int[] input, int k) {
        ArrayList<Integer> list = new ArrayList<>();
        if (input == null || k > input.length || k <= 0) {
            return list;
        }
        Queue<Integer> queue = new PriorityQueue<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2 - o1;
            }
        });

        for (int i = 0; i < k; i++) {
            queue.add(input[i]);
        }
        for (int i = k; i < input.length; i++) {
            int val = queue.peek();
            if (input[i] < val) {
                queue.remove();
                queue.add(input[i]);
            }
        }
        while (!queue.isEmpty()) {
            list.add(queue.poll());
        }
        return list;
    }
}

方法2: 基于快排算法 --> 求数组总第k大的数字,小的放左,大的放右 O(n)

import java.util.ArrayList;

public class Solution {
    public int Partition(int[] input, int l, int r) {
        int x = input[l];
        while (l < r) {
            while (l < r && input[r] >= x) r--;
            input[l] = input[r];
            while (l < r && input[l] <= x) l++;
            input[r] = input[l];
        }
        input[l] = x;
        return l;
    }

    public ArrayList<Integer> GetLeastNumbers_Solution(int[] input, int k) {
        ArrayList<Integer> list = new ArrayList<>();
        if (input == null || k > input.length || k <= 0) {
            return list;
        }
        int l = 0, r = input.length - 1, mid = -1;
        while (mid != k - 1) {
            mid = Partition(input, l, r);
            if (mid > k - 1) r = mid - 1;
            if (mid < k - 1) l = mid + 1;
        }
        for (int i = 0; i < k; i++) {
            list.add(input[i]);
        }
        return list;
    }
}